Merge "Improve AllowedNetworkTypesForReason and refactor PreferredNetworkType"
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
index ebb0070..b1394c1 100644
--- a/apex/appsearch/framework/api/current.txt
+++ b/apex/appsearch/framework/api/current.txt
@@ -22,6 +22,14 @@
     method @NonNull public android.app.appsearch.AppSearchManager.SearchContext.Builder setDatabaseName(@NonNull String);
   }
 
+  public interface AppSearchMigrationHelper {
+    method public void queryAndTransform(@NonNull String, @NonNull android.app.appsearch.AppSearchMigrationHelper.Transformer) throws java.lang.Exception;
+  }
+
+  public static interface AppSearchMigrationHelper.Transformer {
+    method @NonNull public android.app.appsearch.GenericDocument transform(int, int, @NonNull android.app.appsearch.GenericDocument) throws java.lang.Exception;
+  }
+
   public final class AppSearchResult<ValueType> {
     method @Nullable public String getErrorMessage();
     method public int getResultCode();
@@ -99,6 +107,11 @@
     method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig.Builder setCardinality(int);
   }
 
+  public static interface AppSearchSchema.Migrator {
+    method public default void onDowngrade(int, int, @NonNull android.app.appsearch.AppSearchMigrationHelper) throws java.lang.Exception;
+    method public default void onUpgrade(int, int, @NonNull android.app.appsearch.AppSearchMigrationHelper) throws java.lang.Exception;
+  }
+
   public abstract static class AppSearchSchema.PropertyConfig {
     method public int getCardinality();
     method public int getDataType();
@@ -135,7 +148,7 @@
     method public void removeByQuery(@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 removeByUri(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
     method @NonNull 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 public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
+    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>>);
   }
 
   public interface BatchResultCallback<KeyType, ValueType> {
@@ -322,6 +335,7 @@
   }
 
   public final class SetSchemaRequest {
+    method @NonNull public java.util.Map<java.lang.String,android.app.appsearch.AppSearchSchema.Migrator> getMigrators();
     method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
     method @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();
@@ -334,10 +348,26 @@
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
     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.AppSearchSchema.Migrator);
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForPackage(@NonNull String, boolean, @NonNull android.app.appsearch.PackageIdentifier);
     method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForSystemUi(@NonNull String, boolean);
   }
 
+  public class SetSchemaResponse {
+    method @NonNull public java.util.Set<java.lang.String> getDeletedTypes();
+    method @NonNull public java.util.Set<java.lang.String> getIncompatibleTypes();
+    method @NonNull public java.util.Set<java.lang.String> getMigratedTypes();
+    method @NonNull public java.util.List<android.app.appsearch.SetSchemaResponse.MigrationFailure> getMigrationFailures();
+    method public boolean isSuccess();
+  }
+
+  public static class SetSchemaResponse.MigrationFailure {
+    method @NonNull public android.app.appsearch.AppSearchResult<java.lang.Void> getAppSearchResult();
+    method @NonNull public String getNamespace();
+    method @NonNull public String getSchemaType();
+    method @NonNull public String getUri();
+  }
+
 }
 
 package android.app.appsearch.exceptions {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index c4c123c..670f8b9 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -162,7 +162,7 @@
     public void setSchema(
             @NonNull SetSchemaRequest request,
             @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Void>> callback) {
+            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
         Objects.requireNonNull(request);
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
@@ -192,7 +192,18 @@
                     mUserId,
                     new IAppSearchResultCallback.Stub() {
                         public void onResult(AppSearchResult result) {
-                            executor.execute(() -> callback.accept(result));
+                            executor.execute(() -> {
+                                if (result.isSuccess()) {
+                                    callback.accept(
+                                            // TODO(b/151178558) implement Migration in platform.
+                                            AppSearchResult.newSuccessfulResult(
+                                                    new SetSchemaResponse.Builder().setResultCode(
+                                                            result.getResultCode())
+                                                            .build()));
+                                } else {
+                                    callback.accept(result);
+                                }
+                            });
                         }
                     });
             mIsMutated = true;
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchMigrationHelper.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchMigrationHelper.java
new file mode 100644
index 0000000..37943fc
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchMigrationHelper.java
@@ -0,0 +1,65 @@
+/*
+ * 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.annotation.SuppressLint;
+
+/**
+ * The helper class for {@link AppSearchSchema} migration.
+ *
+ * <p>It will query and migrate {@link GenericDocument} in given type to a new version.
+ */
+public interface AppSearchMigrationHelper {
+
+    /**
+     * Queries all documents that need to be migrated to the different version, and transform
+     * documents to that version by passing them to the provided {@link Transformer}.
+     *
+     * @param schemaType The schema that need be updated and migrated {@link GenericDocument} under
+     *     this type.
+     * @param transformer The {@link Transformer} that will upgrade or downgrade a {@link
+     *     GenericDocument} to new version.
+     * @see Transformer#transform
+     */
+    // Rethrow the Generic Exception thrown from the Transformer.
+    @SuppressLint("GenericException")
+    void queryAndTransform(@NonNull String schemaType, @NonNull Transformer transformer)
+            throws Exception;
+
+    /** The class to migrate {@link GenericDocument} between different version. */
+    interface Transformer {
+
+        /**
+         * Translates a {@link GenericDocument} from a version to a different version.
+         *
+         * <p>If the uri, schema type or namespace is changed via the transform, it will apply to
+         * the new {@link GenericDocument}.
+         *
+         * @param currentVersion The current version of the document's schema.
+         * @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.
+         */
+        @NonNull
+        // This method will be overridden by users, allow them to throw any customer Exceptions.
+        @SuppressLint("GenericException")
+        GenericDocument transform(
+                int currentVersion, int finalVersion, @NonNull GenericDocument document)
+                throws Exception;
+    }
+}
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 7f5d202..2e00ff2 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -164,10 +164,10 @@
          * 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 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.
+         * 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
@@ -182,8 +182,9 @@
          * @throws IllegalStateException if the version is negative or the builder has already been
          *     used.
          * @see AppSearchSession#setSchema
+         * @see AppSearchSchema.Migrator
+         * @see SetSchemaRequest.Builder#setMigrator
          */
-        // TODO(b/177266929) link to Migrator in once it's ready.
         @NonNull
         public AppSearchSchema.Builder setVersion(@IntRange(from = 0) int version) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
@@ -859,4 +860,43 @@
             }
         }
     }
+
+    /**
+     * A migrator class to translate {@link GenericDocument} from different version of {@link
+     * AppSearchSchema}
+     */
+    public interface Migrator {
+
+        /**
+         * Migrates {@link GenericDocument} to a newer version of {@link AppSearchSchema}.
+         *
+         * <p>This methods will be invoked only if the {@link SetSchemaRequest} is setting a higher
+         * version number than the current {@link AppSearchSchema} saved in AppSearch.
+         *
+         * @param currentVersion The current version of the document's schema.
+         * @param targetVersion The final version that documents need to be migrated to.
+         * @param helper The helper class could help to query all documents need to be migrated.
+         */
+        // This method will be overridden by users, allow them to throw any customer Exceptions.
+        @SuppressLint("GenericException")
+        default void onUpgrade(
+                int currentVersion, int targetVersion, @NonNull AppSearchMigrationHelper helper)
+                throws Exception {}
+
+        /**
+         * Migrates {@link GenericDocument} to an older version of {@link AppSearchSchema}.
+         *
+         * <p>The methods will be invoked only if the {@link SetSchemaRequest} is setting a higher
+         * version number than the current {@link AppSearchSchema} saved in AppSearch.
+         *
+         * @param currentVersion The current version of the document's schema.
+         * @param targetVersion The final version that documents need to be migrated to.
+         * @param helper The helper class could help to query all documents need to be migrated.
+         */
+        // This method will be overridden by users, allow them to throw any customer Exceptions.
+        @SuppressLint("GenericException")
+        default void onDowngrade(
+                int currentVersion, int targetVersion, @NonNull AppSearchMigrationHelper helper)
+                throws Exception {}
+    }
 }
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 e9c4cb4..1486df3 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -38,16 +38,19 @@
     private final Set<AppSearchSchema> mSchemas;
     private final Set<String> mSchemasNotVisibleToSystemUi;
     private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
+    private final Map<String, AppSearchSchema.Migrator> mMigrators;
     private final boolean mForceOverride;
 
     SetSchemaRequest(
             @NonNull Set<AppSearchSchema> schemas,
             @NonNull Set<String> schemasNotVisibleToSystemUi,
             @NonNull Map<String, Set<PackageIdentifier>> schemasVisibleToPackages,
+            @NonNull Map<String, AppSearchSchema.Migrator> migrators,
             boolean forceOverride) {
         mSchemas = Preconditions.checkNotNull(schemas);
         mSchemasNotVisibleToSystemUi = Preconditions.checkNotNull(schemasNotVisibleToSystemUi);
         mSchemasVisibleToPackages = Preconditions.checkNotNull(schemasVisibleToPackages);
+        mMigrators = Preconditions.checkNotNull(migrators);
         mForceOverride = forceOverride;
     }
 
@@ -81,6 +84,12 @@
         return copy;
     }
 
+    /** Returns the map of {@link android.app.appsearch.AppSearchSchema.Migrator}. */
+    @NonNull
+    public Map<String, AppSearchSchema.Migrator> getMigrators() {
+        return Collections.unmodifiableMap(mMigrators);
+    }
+
     /**
      * Returns a mapping of schema types to the set of packages that have access to that schema
      * type. Each package is represented by a {@link PackageIdentifier}. name and byte[]
@@ -107,6 +116,7 @@
         private final Set<String> mSchemasNotVisibleToSystemUi = new ArraySet<>();
         private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
                 new ArrayMap<>();
+        private final Map<String, AppSearchSchema.Migrator> mMigrators = new ArrayMap<>();
         private boolean mForceOverride = false;
         private boolean mBuilt = false;
 
@@ -197,6 +207,23 @@
         }
 
         /**
+         * Sets the {@link android.app.appsearch.AppSearchSchema.Migrator}.
+         *
+         * @param schemaType The schema type to set migrator on.
+         * @param migrator The migrator translate a document from it's old version to a new
+         *     incompatible version.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects.
+        public Builder setMigrator(
+                @NonNull String schemaType, @NonNull AppSearchSchema.Migrator migrator) {
+            Preconditions.checkNotNull(schemaType);
+            Preconditions.checkNotNull(migrator);
+            mMigrators.put(schemaType, migrator);
+            return this;
+        }
+
+        /**
          * Configures the {@link SetSchemaRequest} to delete any existing documents that don't
          * follow the new schema.
          *
@@ -241,6 +268,7 @@
                     mSchemas,
                     mSchemasNotVisibleToSystemUi,
                     mSchemasVisibleToPackages,
+                    mMigrators,
                     mForceOverride);
         }
     }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
new file mode 100644
index 0000000..90a6f60
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
@@ -0,0 +1,258 @@
+/*
+ * 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 static android.app.appsearch.AppSearchResult.RESULT_OK;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/** The response class of {@link AppSearchSession#setSchema} */
+public class SetSchemaResponse {
+    private final List<MigrationFailure> mMigrationFailures;
+    private final Set<String> mDeletedTypes;
+    private final Set<String> mMigratedTypes;
+    private final Set<String> mIncompatibleTypes;
+    private final @AppSearchResult.ResultCode int mResultCode;
+
+    SetSchemaResponse(
+            @NonNull List<MigrationFailure> migrationFailures,
+            @NonNull Set<String> deletedTypes,
+            @NonNull Set<String> migratedTypes,
+            @NonNull Set<String> incompatibleTypes,
+            @AppSearchResult.ResultCode int resultCode) {
+        mMigrationFailures = Preconditions.checkNotNull(migrationFailures);
+        mDeletedTypes = Preconditions.checkNotNull(deletedTypes);
+        mMigratedTypes = Preconditions.checkNotNull(migratedTypes);
+        mIncompatibleTypes = Preconditions.checkNotNull(incompatibleTypes);
+        mResultCode = resultCode;
+    }
+
+    /**
+     * Returns a {@link List} of all failed {@link MigrationFailure}.
+     *
+     * <p>A {@link MigrationFailure} will be generated if the system trying to save a post-migrated
+     * {@link GenericDocument} but fail.
+     *
+     * <p>{@link MigrationFailure} contains the uri, namespace and schemaType of the post-migrated
+     * {@link GenericDocument} and the error reason. Mostly it will be mismatch the schema it
+     * migrated to.
+     */
+    @NonNull
+    public List<MigrationFailure> getMigrationFailures() {
+        return Collections.unmodifiableList(mMigrationFailures);
+    }
+
+    /**
+     * Returns a {@link Set} of schema type that were deleted by the {@link
+     * AppSearchSession#setSchema} call.
+     */
+    @NonNull
+    public Set<String> getDeletedTypes() {
+        return Collections.unmodifiableSet(mDeletedTypes);
+    }
+
+    /**
+     * Returns a {@link Set} of schema type that were migrated by the {@link
+     * AppSearchSession#setSchema} call.
+     */
+    @NonNull
+    public Set<String> getMigratedTypes() {
+        return Collections.unmodifiableSet(mMigratedTypes);
+    }
+
+    /**
+     * Returns a {@link Set} of schema type whose new definitions set in the {@link
+     * AppSearchSession#setSchema} call were incompatible with the pre-existing schema.
+     *
+     * <p>If a {@link android.app.appsearch.AppSearchSchema.Migrator} is provided for this type and
+     * the migration is success triggered. The type will also appear in {@link #getMigratedTypes()}.
+     *
+     * @see AppSearchSession#setSchema
+     * @see SetSchemaRequest.Builder#setForceOverride
+     */
+    @NonNull
+    public Set<String> getIncompatibleTypes() {
+        return Collections.unmodifiableSet(mIncompatibleTypes);
+    }
+
+    /** Returns {@code true} if all {@link AppSearchSchema}s are successful set to the system. */
+    public boolean isSuccess() {
+        return mResultCode == RESULT_OK;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return "{\n  Does setSchema success? : "
+                + isSuccess()
+                + "\n  failures: "
+                + mMigrationFailures
+                + "\n}";
+    }
+
+    /**
+     * Builder for {@link SetSchemaResponse} objects.
+     *
+     * @hide
+     */
+    public static class Builder {
+        private final List<MigrationFailure> mMigrationFailures = new ArrayList<>();
+        private final Set<String> mDeletedTypes = new ArraySet<>();
+        private final Set<String> mMigratedTypes = new ArraySet<>();
+        private final Set<String> mIncompatibleTypes = new ArraySet<>();
+        private @AppSearchResult.ResultCode int mResultCode = RESULT_OK;
+        private boolean mBuilt = false;
+
+        /** Adds a {@link MigrationFailure}. */
+        @NonNull
+        public Builder setFailure(
+                @NonNull String schemaType,
+                @NonNull String namespace,
+                @NonNull String uri,
+                @NonNull AppSearchResult<Void> failureResult) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(schemaType);
+            Preconditions.checkNotNull(namespace);
+            Preconditions.checkNotNull(uri);
+            Preconditions.checkNotNull(failureResult);
+            Preconditions.checkState(!failureResult.isSuccess());
+            mMigrationFailures.add(new MigrationFailure(schemaType, namespace, uri, failureResult));
+            return this;
+        }
+
+        /** Adds a {@link MigrationFailure}. */
+        @NonNull
+        public Builder setFailure(
+                @NonNull String schemaType,
+                @NonNull String namespace,
+                @NonNull String uri,
+                @AppSearchResult.ResultCode int resultCode,
+                @Nullable String errorMessage) {
+            mMigrationFailures.add(
+                    new MigrationFailure(
+                            schemaType,
+                            namespace,
+                            uri,
+                            AppSearchResult.newFailedResult(resultCode, errorMessage)));
+            return this;
+        }
+
+        /** Adds deletedTypes to the list of deleted schema types. */
+        @NonNull
+        public Builder addDeletedType(@NonNull Collection<String> deletedTypes) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mDeletedTypes.addAll(Preconditions.checkNotNull(deletedTypes));
+            return this;
+        }
+
+        /** Adds incompatibleTypes to the list of incompatible schema types. */
+        @NonNull
+        public Builder addIncompatibleType(@NonNull Collection<String> incompatibleTypes) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mIncompatibleTypes.addAll(Preconditions.checkNotNull(incompatibleTypes));
+            return this;
+        }
+
+        /** Adds migratedTypes to the list of migrated schema types. */
+        @NonNull
+        public Builder addMigratedType(@NonNull String migratedType) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mMigratedTypes.add(Preconditions.checkNotNull(migratedType));
+            return this;
+        }
+
+        /** Sets the {@link AppSearchResult.ResultCode} of the response. */
+        @NonNull
+        public Builder setResultCode(@AppSearchResult.ResultCode int resultCode) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mResultCode = resultCode;
+            return this;
+        }
+
+        /** Builds a {@link SetSchemaResponse} object. */
+        @NonNull
+        public SetSchemaResponse build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new SetSchemaResponse(
+                    mMigrationFailures,
+                    mDeletedTypes,
+                    mMigratedTypes,
+                    mIncompatibleTypes,
+                    mResultCode);
+        }
+    }
+
+    /**
+     * The class represents a post-migrated {@link GenericDocument} that failed to be saved by
+     * {@link AppSearchSession#setSchema}.
+     */
+    public static class MigrationFailure {
+        private final String mSchemaType;
+        private final String mNamespace;
+        private final String mUri;
+        AppSearchResult<Void> mFailureResult;
+
+        MigrationFailure(
+                @NonNull String schemaType,
+                @NonNull String namespace,
+                @NonNull String uri,
+                @NonNull AppSearchResult<Void> result) {
+            mSchemaType = schemaType;
+            mNamespace = namespace;
+            mUri = uri;
+            mFailureResult = result;
+        }
+
+        /** Returns the schema type of the {@link GenericDocument} that fails to be migrated. */
+        @NonNull
+        public String getSchemaType() {
+            return mSchemaType;
+        }
+
+        /** Returns the namespace of the {@link GenericDocument} that fails to be migrated. */
+        @NonNull
+        public String getNamespace() {
+            return mNamespace;
+        }
+
+        /** Returns the uri of the {@link GenericDocument} that fails to be migrated. */
+        @NonNull
+        public String getUri() {
+            return mUri;
+        }
+
+        /**
+         * Returns the {@link AppSearchResult} that indicates why the post-migrated {@link
+         * GenericDocument} fails to be saved.
+         */
+        @NonNull
+        public AppSearchResult<Void> getAppSearchResult() {
+            return mFailureResult;
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResult.java
new file mode 100644
index 0000000..f04ace6
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResult.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class represents the results of setSchema().
+ *
+ * @hide
+ */
+public class SetSchemaResult {
+
+    public static final String DELETED_SCHEMA_TYPES_FIELD = "deletedSchemaTypes";
+    public static final String INCOMPATIBLE_SCHEMA_TYPES_FIELD = "incompatibleSchemaTypes";
+    public static final String RESULT_CODE_FIELD = "resultCode";
+    private final List<String> mDeletedSchemaTypes;
+    private final List<String> mIncompatibleSchemaTypes;
+    private final Bundle mBundle;
+
+    SetSchemaResult(@NonNull Bundle bundle) {
+        mBundle = Preconditions.checkNotNull(bundle);
+        mDeletedSchemaTypes =
+                Preconditions.checkNotNull(mBundle.getStringArrayList(DELETED_SCHEMA_TYPES_FIELD));
+        mIncompatibleSchemaTypes =
+                Preconditions.checkNotNull(
+                        mBundle.getStringArrayList(INCOMPATIBLE_SCHEMA_TYPES_FIELD));
+    }
+
+    /** Returns the {@link Bundle} of this class. */
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    /** returns all deleted schema types in this setSchema call. */
+    @NonNull
+    public List<String> getDeletedSchemaTypes() {
+        return Collections.unmodifiableList(mDeletedSchemaTypes);
+    }
+
+    /** returns all incompatible schema types in this setSchema call. */
+    @NonNull
+    public List<String> getIncompatibleSchemaTypes() {
+        return Collections.unmodifiableList(mIncompatibleSchemaTypes);
+    }
+
+    /**
+     * returns the {@link android.app.appsearch.AppSearchResult.ResultCode} of the {@link
+     * AppSearchSession#setSchema} call.
+     */
+    public int getResultCode() {
+        return mBundle.getInt(RESULT_CODE_FIELD);
+    }
+
+    /** Builder for {@link SetSchemaResult} objects. */
+    public static final class Builder {
+        private final ArrayList<String> mDeletedSchemaTypes = new ArrayList<>();
+        private final ArrayList<String> mIncompatibleSchemaTypes = new ArrayList<>();
+        @AppSearchResult.ResultCode private int mResultCode;
+        private boolean mBuilt = false;
+
+        /** Adds a deletedSchemaTypes to the {@link SetSchemaResult}. */
+        @NonNull
+        public Builder addDeletedSchemaType(@NonNull String deletedSchemaType) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mDeletedSchemaTypes.add(Preconditions.checkNotNull(deletedSchemaType));
+            return this;
+        }
+
+        /** Adds a incompatible SchemaTypes to the {@link SetSchemaResult}. */
+        @NonNull
+        public Builder addIncompatibleSchemaType(@NonNull String incompatibleSchemaTypes) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mIncompatibleSchemaTypes.add(Preconditions.checkNotNull(incompatibleSchemaTypes));
+            return this;
+        }
+
+        /**
+         * Sets the {@link android.app.appsearch.AppSearchResult.ResultCode} of the {@link
+         * AppSearchSession#setSchema} call to the {@link SetSchemaResult}
+         */
+        @NonNull
+        public Builder setResultCode(@AppSearchResult.ResultCode int resultCode) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mResultCode = resultCode;
+            return this;
+        }
+
+        /** Builds a {@link SetSchemaResult}. */
+        @NonNull
+        public SetSchemaResult build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(
+                    SetSchemaResult.DELETED_SCHEMA_TYPES_FIELD, mDeletedSchemaTypes);
+            bundle.putStringArrayList(
+                    SetSchemaResult.INCOMPATIBLE_SCHEMA_TYPES_FIELD, mIncompatibleSchemaTypes);
+            bundle.putInt(RESULT_CODE_FIELD, mResultCode);
+            mBuilt = true;
+            return new SetSchemaResult(bundle);
+        }
+    }
+}
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 651ccd9..592b8b9 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
@@ -25,6 +25,7 @@
 import android.app.appsearch.PackageIdentifier;
 import android.app.appsearch.SearchResultPage;
 import android.app.appsearch.SearchSpec;
+import android.app.appsearch.SetSchemaResult;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 import android.os.Bundle;
@@ -36,9 +37,11 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.ResultCodeToProtoConverter;
 import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
 import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
 import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.SetSchemaResultToProtoConverter;
 import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
 
 import com.google.android.icing.IcingSearchEngine;
@@ -259,7 +262,8 @@
      *     which do not comply with the new schema will be deleted.
      * @throws AppSearchException on IcingSearchEngine error.
      */
-    public void setSchema(
+    @NonNull
+    public SetSchemaResult setSchema(
             @NonNull String packageName,
             @NonNull String databaseName,
             @NonNull List<AppSearchSchema> schemas,
@@ -273,8 +277,9 @@
 
             SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
             for (int i = 0; i < schemas.size(); i++) {
+                AppSearchSchema schema = schemas.get(i);
                 SchemaTypeConfigProto schemaTypeProto =
-                        SchemaToProtoConverter.toSchemaTypeConfigProto(schemas.get(i));
+                        SchemaToProtoConverter.toSchemaTypeConfigProto(schema);
                 newSchemaBuilder.addTypes(schemaTypeProto);
             }
 
@@ -293,16 +298,10 @@
             try {
                 checkSuccess(setSchemaResultProto.getStatus());
             } catch (AppSearchException e) {
-                // Improve the error message by merging in information about incompatible types.
                 if (setSchemaResultProto.getDeletedSchemaTypesCount() > 0
                         || setSchemaResultProto.getIncompatibleSchemaTypesCount() > 0) {
-                    String newMessage =
-                            e.getMessage()
-                                    + "\n  Deleted types: "
-                                    + setSchemaResultProto.getDeletedSchemaTypesList()
-                                    + "\n  Incompatible types: "
-                                    + setSchemaResultProto.getIncompatibleSchemaTypesList();
-                    throw new AppSearchException(e.getResultCode(), newMessage, e.getCause());
+                    return SetSchemaResultToProtoConverter.toSetSchemaResult(
+                            setSchemaResultProto, prefix);
                 } else {
                     throw e;
                 }
@@ -339,6 +338,7 @@
                 // incompatible schemas.
                 checkForOptimizeLocked(/* force= */ true);
             }
+            return SetSchemaResultToProtoConverter.toSetSchemaResult(setSchemaResultProto, prefix);
         } finally {
             mReadWriteLock.writeLock().unlock();
         }
@@ -796,6 +796,8 @@
      * <p>If the app crashes before a call to PersistToDisk(), Icing would trigger a costly recovery
      * process in next initialization. After that, Icing would still be able to recover all written
      * data.
+     *
+     * @throws AppSearchException on any error that AppSearch persist data to disk.
      */
     public void persistToDisk() throws AppSearchException {
         PersistToDiskResultProto persistToDiskResultProto =
@@ -1374,28 +1376,8 @@
      * @return AppSearchException with the parallel error code.
      */
     private static AppSearchException statusProtoToAppSearchException(StatusProto statusProto) {
-        switch (statusProto.getCode()) {
-            case INVALID_ARGUMENT:
-                return new AppSearchException(
-                        AppSearchResult.RESULT_INVALID_ARGUMENT, statusProto.getMessage());
-            case NOT_FOUND:
-                return new AppSearchException(
-                        AppSearchResult.RESULT_NOT_FOUND, statusProto.getMessage());
-            case FAILED_PRECONDITION:
-                // Fallthrough
-            case ABORTED:
-                // Fallthrough
-            case INTERNAL:
-                return new AppSearchException(
-                        AppSearchResult.RESULT_INTERNAL_ERROR, statusProto.getMessage());
-            case OUT_OF_SPACE:
-                return new AppSearchException(
-                        AppSearchResult.RESULT_OUT_OF_SPACE, statusProto.getMessage());
-            default:
-                // Some unknown/unsupported error
-                return new AppSearchException(
-                        AppSearchResult.RESULT_UNKNOWN_ERROR,
-                        "Unknown IcingSearchEngine status code: " + statusProto.getCode());
-        }
+        return new AppSearchException(
+                ResultCodeToProtoConverter.toResultCode(statusProto.getCode()),
+                statusProto.getMessage());
     }
 }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java
new file mode 100644
index 0000000..e340de0
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java
@@ -0,0 +1,62 @@
+/*
+ * 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 com.android.server.appsearch.external.localstorage.converter;
+
+import android.annotation.NonNull;
+import android.app.appsearch.AppSearchResult;
+import android.util.Log;
+
+import com.google.android.icing.proto.StatusProto;
+
+/**
+ * Translates an {@link StatusProto.Code} into a {@link AppSearchResult.ResultCode}
+ *
+ * @hide
+ */
+public final class ResultCodeToProtoConverter {
+
+    private static final String TAG = "AppSearchResultCodeToPr";
+
+    private ResultCodeToProtoConverter() {}
+
+    /** Converts an {@link StatusProto.Code} into a {@link AppSearchResult.ResultCode}. */
+    public static @AppSearchResult.ResultCode int toResultCode(
+            @NonNull StatusProto.Code statusCode) {
+        switch (statusCode) {
+            case OK:
+                return AppSearchResult.RESULT_OK;
+            case OUT_OF_SPACE:
+                return AppSearchResult.RESULT_OUT_OF_SPACE;
+            case INTERNAL:
+                return AppSearchResult.RESULT_INTERNAL_ERROR;
+            case UNKNOWN:
+                return AppSearchResult.RESULT_UNKNOWN_ERROR;
+            case NOT_FOUND:
+                return AppSearchResult.RESULT_NOT_FOUND;
+            case INVALID_ARGUMENT:
+                return AppSearchResult.RESULT_INVALID_ARGUMENT;
+            default:
+                // Some unknown/unsupported error
+                Log.e(
+                        TAG,
+                        "Cannot convert IcingSearchEngine status code: "
+                                + statusCode
+                                + " to AppSearchResultCode.");
+                return AppSearchResult.RESULT_INTERNAL_ERROR;
+        }
+    }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResultToProtoConverter.java
new file mode 100644
index 0000000..e1e7d46
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResultToProtoConverter.java
@@ -0,0 +1,64 @@
+/*
+ * 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 com.android.server.appsearch.external.localstorage.converter;
+
+import android.annotation.NonNull;
+import android.app.appsearch.SetSchemaResult;
+
+import com.android.internal.util.Preconditions;
+
+import com.google.android.icing.proto.SetSchemaResultProto;
+
+/**
+ * Translates a {@link SetSchemaResultProto} into {@link SetSchemaResult}.
+ *
+ * @hide
+ */
+public class SetSchemaResultToProtoConverter {
+
+    private SetSchemaResultToProtoConverter() {}
+
+    /**
+     * Translate a {@link SetSchemaResultProto} into {@link SetSchemaResult}.
+     *
+     * @param proto The {@link SetSchemaResultProto} containing results.
+     * @param prefix The prefix need to removed from schemaTypes
+     * @return {@link SetSchemaResult} of results.
+     */
+    @NonNull
+    public static SetSchemaResult toSetSchemaResult(
+            @NonNull SetSchemaResultProto proto, @NonNull String prefix) {
+        Preconditions.checkNotNull(proto);
+        Preconditions.checkNotNull(prefix);
+        SetSchemaResult.Builder builder =
+                new SetSchemaResult.Builder()
+                        .setResultCode(
+                                ResultCodeToProtoConverter.toResultCode(
+                                        proto.getStatus().getCode()));
+
+        for (int i = 0; i < proto.getDeletedSchemaTypesCount(); i++) {
+            builder.addDeletedSchemaType(proto.getDeletedSchemaTypes(i).substring(prefix.length()));
+        }
+
+        for (int i = 0; i < proto.getIncompatibleSchemaTypesCount(); i++) {
+            builder.addIncompatibleSchemaType(
+                    proto.getIncompatibleSchemaTypes(i).substring(prefix.length()));
+        }
+
+        return builder.build();
+    }
+}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 51aeb89..2774181 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-I03df55376689c1557c651d5b9671c40da1c35955
+I3fd4c96bf775c2539d744c416cdbf1d3c9544f03
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 c2c1d7c..f8d0d80 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
@@ -33,6 +33,7 @@
 import android.app.appsearch.SearchResultsShim;
 import android.app.appsearch.SearchSpec;
 import android.app.appsearch.SetSchemaRequest;
+import android.app.appsearch.SetSchemaResponse;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 
@@ -85,8 +86,8 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> setSchema(@NonNull SetSchemaRequest request) {
-        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
+    public ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request) {
+        SettableFuture<AppSearchResult<SetSchemaResponse>> future = SettableFuture.create();
         mAppSearchSession.setSchema(request, mExecutor, future::set);
         return Futures.transformAsync(future, this::transformResult, mExecutor);
     }
@@ -159,6 +160,16 @@
         mAppSearchSession.close();
     }
 
+    @Override
+    @NonNull
+    public ListenableFuture<Void> maybeFlush() {
+        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
+        // The data in platform will be flushed by scheduled task. AppSearchSession won't do
+        // anything extra flush.
+        future.set(AppSearchResult.newSuccessfulResult(null));
+        return Futures.transformAsync(future, this::transformResult, mExecutor);
+    }
+
     private <T> ListenableFuture<T> transformResult(
             @NonNull AppSearchResult<T> result) throws AppSearchException {
         if (!result.isSuccess()) {
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 ff91f59..e8ea6ef 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
@@ -69,12 +69,19 @@
      * {@link AppSearchResult#RESULT_INVALID_SCHEMA} and a message describing the incompatibility.
      * In this case the previously set schema will remain active.
      *
-     * <p>If you need to make non-backwards-compatible changes as described above, you can set the
-     * {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In this case,
-     * instead of completing its future with an {@link
-     * android.app.appsearch.exceptions.AppSearchException} with the {@link
-     * AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not compatible
-     * with the new schema will be deleted and the incompatible schema will be applied.
+     * <p>If you need to make non-backwards-compatible changes as described above, you can either:
+     *
+     * <ul>
+     *   <li>Set the {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In
+     *       this case, instead of completing its future with an {@link
+     *       android.app.appsearch.exceptions.AppSearchException} with the {@link
+     *       AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not
+     *       compatible with the new schema will be deleted and the incompatible schema will be
+     *       applied.
+     *   <li>Add a {@link android.app.appsearch.AppSearchSchema.Migrator} for each incompatible type
+     *       and make no deletion. The migrator will migrate documents from it's old schema version
+     *       to the new version. See the migration section below.
+     * </ul>
      *
      * <p>It is a no-op to set the same schema as has been previously set; this is handled
      * efficiently.
@@ -85,13 +92,34 @@
      * Visibility settings for a schema type do not apply or persist across {@link
      * SetSchemaRequest}s.
      *
+     * <p>Migration: make non-backwards-compatible changes will delete all stored documents in old
+     * schema. You can save your documents by setting {@link
+     * android.app.appsearch.AppSearchSchema.Migrator} via the {@link
+     * SetSchemaRequest.Builder#setMigrator} for each type you want to save.
+     *
+     * <p>{@link android.app.appsearch.AppSearchSchema.Migrator#onDowngrade} or {@link
+     * android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} will be triggered if the version
+     * number of the schema stored in AppSearch is different with the version in the request.
+     *
+     * <p>If any error or Exception occurred in the {@link
+     * android.app.appsearch.AppSearchSchema.Migrator#onDowngrade}, {@link
+     * android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} or {@link
+     * android.app.appsearch.AppSearchMigrationHelper.Transformer#transform}, the migration will be
+     * terminated, the setSchema request will be rejected unless the schema changes are
+     * backwards-compatible, and stored documents won't have any observable changes.
+     *
      * @param request The schema update request.
-     * @return The pending result of performing this operation.
+     * @return The pending {@link SetSchemaResponse} of performing this operation. Success if the
+     *     the schema has been set and any migrations has been done. Otherwise, the failure {@link
+     *     android.app.appsearch.SetSchemaResponse.MigrationFailure} indicates which document is
+     *     fail to be migrated.
+     * @see android.app.appsearch.AppSearchSchema.Migrator
+     * @see android.app.appsearch.AppSearchMigrationHelper.Transformer
      */
     // TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
     //  exposed.
     @NonNull
-    ListenableFuture<Void> setSchema(@NonNull SetSchemaRequest request);
+    ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request);
 
     /**
      * Retrieves the schema most recently successfully provided to {@link #setSchema}.
@@ -227,6 +255,17 @@
             @NonNull String queryExpression, @NonNull SearchSpec searchSpec);
 
     /**
+     * Flush all schema and document updates, additions, and deletes to disk if possible.
+     *
+     * @return The pending result of performing this operation. {@link
+     *     android.app.appsearch.exceptions.AppSearchException} with {@link
+     *     AppSearchResult#RESULT_INTERNAL_ERROR} will be set to the future if we hit error when
+     *     save to disk.
+     */
+    @NonNull
+    ListenableFuture<Void> maybeFlush();
+
+    /**
      * Closes the {@link AppSearchSessionShim} to persist all schema and document updates,
      * additions, and deletes to disk.
      */
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 13858a3..20fb909 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
@@ -25,6 +25,7 @@
 import android.app.appsearch.GetByUriRequest;
 import android.app.appsearch.SearchResult;
 import android.app.appsearch.SearchResultsShim;
+import android.app.appsearch.SetSchemaResponse;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -42,6 +43,15 @@
         return result;
     }
 
+    // TODO(b/151178558) check setSchemaResponse.xxxtypes for the test need to verify.
+    public static void checkIsSetSchemaResponseSuccess(Future<SetSchemaResponse> future)
+            throws Exception {
+        SetSchemaResponse setSchemaResponse = future.get();
+        assertWithMessage("SetSchemaResponse not successful.")
+                .that(setSchemaResponse.isSuccess())
+                .isTrue();
+    }
+
     public static List<GenericDocument> doGet(
             AppSearchSessionShim session, String namespace, String... uris) throws Exception {
         AppSearchBatchResult<String, GenericDocument> result =
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 9088db8..260c8a4 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -20,6 +20,7 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.storage.DiskInfo;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
@@ -30,6 +31,8 @@
 
 public final class Sm {
     private static final String TAG = "Sm";
+    private static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
+            "persist.sys.vold_app_data_isolation_enabled";
 
     IStorageManager mSm;
 
@@ -254,6 +257,10 @@
     }
 
     public void runDisableAppDataIsolation() throws RemoteException {
+        if (!SystemProperties.getBoolean(
+                ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false)) {
+            throw new IllegalStateException("Storage app data isolation is not enabled.");
+        }
         final String pkgName = nextArg();
         final int pid = Integer.parseInt(nextArg());
         final int userId = Integer.parseInt(nextArg());
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 6f818a9..775c8f6 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -5418,10 +5418,6 @@
 android.net.nsd.INsdManager
 android.net.nsd.NsdManager$ServiceHandler
 android.net.nsd.NsdManager
-android.net.rtp.AudioCodec
-android.net.rtp.AudioGroup
-android.net.rtp.AudioStream
-android.net.rtp.RtpStream
 android.net.sip.ISipService$Default
 android.net.sip.ISipService$Stub$Proxy
 android.net.sip.ISipService$Stub
diff --git a/config/preloaded-classes-denylist b/config/preloaded-classes-denylist
index 8ee633c..43a8a87 100644
--- a/config/preloaded-classes-denylist
+++ b/config/preloaded-classes-denylist
@@ -6,3 +6,6 @@
 android.widget.Magnifier
 com.android.server.BootReceiver$2
 gov.nist.core.net.DefaultNetworkLayer
+android.net.rtp.AudioGroup
+android.net.rtp.AudioStream
+android.net.rtp.RtpStream
diff --git a/core/api/current.txt b/core/api/current.txt
index e9edc36..03ec416 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -12384,6 +12384,7 @@
     field public static final String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
     field public static final String FEATURE_SECURELY_REMOVES_USERS = "android.software.securely_removes_users";
     field public static final String FEATURE_SECURE_LOCK_SCREEN = "android.software.secure_lock_screen";
+    field public static final String FEATURE_SECURITY_MODEL_COMPATIBLE = "android.hardware.security.model.compatible";
     field public static final String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer";
     field public static final String FEATURE_SENSOR_AMBIENT_TEMPERATURE = "android.hardware.sensor.ambient_temperature";
     field public static final String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer";
@@ -42644,6 +42645,7 @@
     field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192
     field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194
     field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386
+    field public static final int CODE_NETWORK_CONGESTION = 1624; // 0x658
     field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9
     field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0
     field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 6ed09af..5d61aca 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -40,6 +40,22 @@
 
 }
 
+package android.content {
+
+  public abstract class Context {
+    method @NonNull public android.os.UserHandle getUser();
+  }
+
+}
+
+package android.content.pm {
+
+  public abstract class PackageManager {
+    method @NonNull public String getPermissionControllerPackageName();
+  }
+
+}
+
 package android.content.rollback {
 
   public class RollbackManagerFrameworkInitializer {
@@ -136,6 +152,14 @@
 
 package android.net {
 
+  public class ConnectivityManager {
+    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);
+  }
+
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    field public static final int TRANSPORT_TEST = 7; // 0x7
+  }
+
   public final class TcpRepairWindow {
     ctor public TcpRepairWindow(int, int, int, int, int, int);
     field public final int maxWindow;
@@ -170,6 +194,10 @@
     method public final void markVintfStability();
   }
 
+  public static class Build.VERSION {
+    field public static final int FIRST_SDK_INT;
+  }
+
   public interface Parcelable {
     method public default int getStability();
   }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 2d5f315..bd1c5c7 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6847,6 +6847,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 @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);
@@ -6856,6 +6857,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
+    method public void unregisterQosCallback(@NonNull android.net.QosCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
     field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
     field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
@@ -7049,6 +7051,8 @@
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
     method public void onAutomaticReconnectDisabled();
     method public void onNetworkUnwanted();
+    method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
+    method public void onQosCallbackUnregistered(int);
     method public void onRemoveKeepalivePacketFilter(int);
     method public void onSaveAcceptUnvalidated(boolean);
     method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
@@ -7059,6 +7063,9 @@
     method public final void sendLinkProperties(@NonNull android.net.LinkProperties);
     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 sendSocketKeepaliveEvent(int, int);
     method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
     method public void unregister();
@@ -7145,6 +7152,9 @@
     method public abstract void onRequestScores(android.net.NetworkKey[]);
   }
 
+  public class NetworkReleasedException extends java.lang.Exception {
+  }
+
   public class NetworkRequest implements android.os.Parcelable {
     method @Nullable public String getRequestorPackageName();
     method public int getRequestorUid();
@@ -7217,6 +7227,46 @@
     ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
   }
 
+  public abstract class QosCallback {
+    ctor public QosCallback();
+    method public void onError(@NonNull android.net.QosCallbackException);
+    method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
+    method public void onQosSessionLost(@NonNull android.net.QosSession);
+  }
+
+  public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
+  }
+
+  public final class QosCallbackException extends java.lang.Exception {
+  }
+
+  public abstract class QosFilter {
+    method @NonNull public abstract android.net.Network getNetwork();
+  }
+
+  public final class QosSession implements android.os.Parcelable {
+    ctor public QosSession(int, int);
+    method public int describeContents();
+    method public int getSessionId();
+    method public int getSessionType();
+    method public long getUniqueId();
+    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
+  }
+
+  public interface QosSessionAttributes {
+  }
+
+  public final class QosSocketInfo implements android.os.Parcelable {
+    ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
+    method public int describeContents();
+    method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
+    method @NonNull public android.net.Network getNetwork();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
+  }
+
   public final class RouteInfo implements android.os.Parcelable {
     ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
     ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
@@ -7262,6 +7312,12 @@
     field public static final int SUCCESS = 0; // 0x0
   }
 
+  public class SocketLocalAddressChangedException extends java.lang.Exception {
+  }
+
+  public class SocketNotBoundException extends java.lang.Exception {
+  }
+
   public final class StaticIpConfiguration implements android.os.Parcelable {
     ctor public StaticIpConfiguration();
     ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
@@ -9490,10 +9546,10 @@
     method @NonNull @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
   }
 
-  public final class CarrierMessagingServiceWrapper {
+  public final class CarrierMessagingServiceWrapper implements java.lang.AutoCloseable {
     ctor public CarrierMessagingServiceWrapper();
     method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull Runnable);
-    method public void disposeConnection(@NonNull android.content.Context);
+    method public void disconnect();
     method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
     method public void receiveSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
     method public void sendDataSms(@NonNull byte[], int, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
@@ -11881,6 +11937,19 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public final class EpsBearerQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
+    method @NonNull public static android.telephony.data.EpsBearerQosSessionAttributes create(@NonNull android.os.Parcel);
+    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 @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 abstract class QualifiedNetworksService extends android.app.Service {
     ctor public QualifiedNetworksService();
     method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
@@ -13421,6 +13490,164 @@
 
 }
 
+package android.uwb {
+
+  public final class AngleMeasurement implements android.os.Parcelable {
+    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();
+    method @FloatRange(from=-3.141592653589793, to=3.141592653589793) public double getRadians();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR;
+  }
+
+  public static final class AngleMeasurement.Builder {
+    ctor public AngleMeasurement.Builder();
+    method @NonNull public android.uwb.AngleMeasurement build();
+    method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double);
+    method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double);
+    method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double);
+  }
+
+  public final class AngleOfArrivalMeasurement implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.uwb.AngleMeasurement getAltitude();
+    method @NonNull public android.uwb.AngleMeasurement getAzimuth();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleOfArrivalMeasurement> CREATOR;
+  }
+
+  public static final class AngleOfArrivalMeasurement.Builder {
+    ctor public AngleOfArrivalMeasurement.Builder();
+    method @NonNull public android.uwb.AngleOfArrivalMeasurement build();
+    method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement);
+    method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement);
+  }
+
+  public final class DistanceMeasurement implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
+    method public double getErrorMeters();
+    method public double getMeters();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.DistanceMeasurement> CREATOR;
+  }
+
+  public static final class DistanceMeasurement.Builder {
+    ctor public DistanceMeasurement.Builder();
+    method @NonNull public android.uwb.DistanceMeasurement build();
+    method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(double);
+    method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(double);
+    method @NonNull public android.uwb.DistanceMeasurement.Builder setMeters(double);
+  }
+
+  public final class RangingMeasurement implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.uwb.AngleOfArrivalMeasurement getAngleOfArrivalMeasurement();
+    method @Nullable public android.uwb.DistanceMeasurement getDistanceMeasurement();
+    method public long getElapsedRealtimeNanos();
+    method @NonNull public android.uwb.UwbAddress getRemoteDeviceAddress();
+    method public int getStatus();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.RangingMeasurement> CREATOR;
+    field public static final int RANGING_STATUS_FAILURE_OUT_OF_RANGE = 1; // 0x1
+    field public static final int RANGING_STATUS_FAILURE_UNKNOWN_ERROR = -1; // 0xffffffff
+    field public static final int RANGING_STATUS_SUCCESS = 0; // 0x0
+  }
+
+  public static final class RangingMeasurement.Builder {
+    ctor public RangingMeasurement.Builder();
+    method @NonNull public android.uwb.RangingMeasurement build();
+    method @NonNull public android.uwb.RangingMeasurement.Builder setAngleOfArrivalMeasurement(@NonNull android.uwb.AngleOfArrivalMeasurement);
+    method @NonNull public android.uwb.RangingMeasurement.Builder setDistanceMeasurement(@NonNull android.uwb.DistanceMeasurement);
+    method @NonNull public android.uwb.RangingMeasurement.Builder setElapsedRealtimeNanos(long);
+    method @NonNull public android.uwb.RangingMeasurement.Builder setRemoteDeviceAddress(@NonNull android.uwb.UwbAddress);
+    method @NonNull public android.uwb.RangingMeasurement.Builder setStatus(int);
+  }
+
+  public final class RangingReport implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.uwb.RangingMeasurement> getMeasurements();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.RangingReport> CREATOR;
+  }
+
+  public static final class RangingReport.Builder {
+    ctor public RangingReport.Builder();
+    method @NonNull public android.uwb.RangingReport.Builder addMeasurement(@NonNull android.uwb.RangingMeasurement);
+    method @NonNull public android.uwb.RangingReport.Builder addMeasurements(@NonNull java.util.List<android.uwb.RangingMeasurement>);
+    method @NonNull public android.uwb.RangingReport build();
+  }
+
+  public final class RangingSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public void reconfigure(@NonNull android.os.PersistableBundle);
+    method public void start(@NonNull android.os.PersistableBundle);
+    method public void stop();
+  }
+
+  public static interface RangingSession.Callback {
+    method public void onClosed(int, @NonNull android.os.PersistableBundle);
+    method public void onOpenFailed(int, @NonNull android.os.PersistableBundle);
+    method public void onOpened(@NonNull android.uwb.RangingSession);
+    method public void onReconfigureFailed(int, @NonNull android.os.PersistableBundle);
+    method public void onReconfigured(@NonNull android.os.PersistableBundle);
+    method public void onReportReceived(@NonNull android.uwb.RangingReport);
+    method public void onStartFailed(int, @NonNull android.os.PersistableBundle);
+    method public void onStarted(@NonNull android.os.PersistableBundle);
+    method public void onStopFailed(int, @NonNull android.os.PersistableBundle);
+    method public void onStopped();
+    field public static final int REASON_BAD_PARAMETERS = 3; // 0x3
+    field public static final int REASON_GENERIC_ERROR = 4; // 0x4
+    field public static final int REASON_LOCAL_REQUEST = 1; // 0x1
+    field public static final int REASON_MAX_SESSIONS_REACHED = 5; // 0x5
+    field public static final int REASON_PROTOCOL_SPECIFIC_ERROR = 7; // 0x7
+    field public static final int REASON_REMOTE_REQUEST = 2; // 0x2
+    field public static final int REASON_SYSTEM_POLICY = 6; // 0x6
+    field public static final int REASON_UNKNOWN = 0; // 0x0
+  }
+
+  public final class UwbAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public static android.uwb.UwbAddress fromBytes(@NonNull byte[]);
+    method public int size();
+    method @NonNull public byte[] toBytes();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.uwb.UwbAddress> CREATOR;
+    field public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8; // 0x8
+    field public static final int SHORT_ADDRESS_BYTE_LENGTH = 2; // 0x2
+  }
+
+  public final class UwbManager {
+    method public long elapsedRealtimeResolutionNanos();
+    method public int getAngleOfArrivalSupport();
+    method public int getMaxRemoteDevicesPerInitiatorSession();
+    method public int getMaxRemoteDevicesPerResponderSession();
+    method public int getMaxSimultaneousSessions();
+    method @NonNull public android.os.PersistableBundle getSpecificationInfo();
+    method @NonNull public java.util.List<java.lang.Integer> getSupportedChannelNumbers();
+    method @NonNull public java.util.Set<java.lang.Integer> getSupportedPreambleCodeIndices();
+    method public boolean isRangingSupported();
+    method @NonNull public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+    method public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
+    method public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
+    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D = 2; // 0x2
+    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL = 3; // 0x3
+    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL = 4; // 0x4
+    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE = 1; // 0x1
+  }
+
+  public static interface UwbManager.AdapterStateCallback {
+    method public void onStateChanged(boolean, int);
+    field public static final int STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED = 1; // 0x1
+    field public static final int STATE_CHANGED_REASON_ERROR_UNKNOWN = 4; // 0x4
+    field public static final int STATE_CHANGED_REASON_SESSION_STARTED = 0; // 0x0
+    field public static final int STATE_CHANGED_REASON_SYSTEM_BOOT = 3; // 0x3
+    field public static final int STATE_CHANGED_REASON_SYSTEM_POLICY = 2; // 0x2
+  }
+
+}
+
 package android.view {
 
   public abstract class Window {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index af1e0b9..2efa87e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -377,6 +377,7 @@
 package android.app.admin {
 
   public class DevicePolicyManager {
+    method public int checkProvisioningPreCondition(@Nullable String, @NonNull String);
     method @Nullable public android.os.UserHandle createAndProvisionManagedProfile(@NonNull android.app.admin.ManagedProfileProvisioningParams) throws android.app.admin.ProvisioningException;
     method public void forceUpdateUserSetupComplete();
     method public long getLastBugReportRequestTime();
@@ -386,9 +387,27 @@
     method public boolean isCurrentInputMethodSetByOwner();
     method public boolean isFactoryResetProtectionPolicySupported();
     method @NonNull public static String operationToString(int);
+    method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
     method @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public void setNextOperationSafety(int, boolean);
     field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
     field public static final String ACTION_MANAGED_PROFILE_CREATED = "android.app.action.MANAGED_PROFILE_CREATED";
+    field public static final String ACTION_PROVISIONED_MANAGED_DEVICE = "android.app.action.PROVISIONED_MANAGED_DEVICE";
+    field public static final int CODE_ACCOUNTS_NOT_EMPTY = 6; // 0x6
+    field public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11; // 0xb
+    field public static final int CODE_DEVICE_ADMIN_NOT_SUPPORTED = 13; // 0xd
+    field public static final int CODE_HAS_DEVICE_OWNER = 1; // 0x1
+    field public static final int CODE_HAS_PAIRED = 8; // 0x8
+    field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9
+    field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5
+    field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7
+    field public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc
+    field public static final int CODE_OK = 0; // 0x0
+    field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf
+    field public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe
+    field public static final int CODE_SYSTEM_USER = 10; // 0xa
+    field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2
+    field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3
+    field public static final int CODE_USER_SETUP_COMPLETED = 4; // 0x4
     field public static final int OPERATION_CLEAR_APPLICATION_USER_DATA = 23; // 0x17
     field public static final int OPERATION_CREATE_AND_MANAGE_USER = 5; // 0x5
     field public static final int OPERATION_INSTALL_CA_CERT = 24; // 0x18
@@ -432,10 +451,33 @@
     field public static final int PROVISIONING_RESULT_ADMIN_PACKAGE_INSTALLATION_FAILED = 3; // 0x3
     field public static final int PROVISIONING_RESULT_PRE_CONDITION_FAILED = 1; // 0x1
     field public static final int PROVISIONING_RESULT_PROFILE_CREATION_FAILED = 2; // 0x2
+    field public static final int PROVISIONING_RESULT_REMOVE_NON_REQUIRED_APPS_FAILED = 6; // 0x6
     field public static final int PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED = 4; // 0x4
+    field public static final int PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED = 7; // 0x7
     field public static final int PROVISIONING_RESULT_STARTING_PROFILE_FAILED = 5; // 0x5
   }
 
+  public final class FullyManagedDeviceProvisioningParams implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.content.ComponentName getDeviceAdminComponentName();
+    method public long getLocalTime();
+    method @Nullable public java.util.Locale getLocale();
+    method @NonNull public String getOwnerName();
+    method @Nullable public String getTimeZone();
+    method public boolean isLeaveAllSystemAppsEnabled();
+    method public void writeToParcel(@NonNull android.os.Parcel, @Nullable int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FullyManagedDeviceProvisioningParams> CREATOR;
+  }
+
+  public static final class FullyManagedDeviceProvisioningParams.Builder {
+    ctor public FullyManagedDeviceProvisioningParams.Builder(@NonNull android.content.ComponentName, @NonNull String);
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams build();
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLeaveAllSystemAppsEnabled(boolean);
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocalTime(long);
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocale(@Nullable java.util.Locale);
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setTimeZone(@Nullable String);
+  }
+
   public final class ManagedProfileProvisioningParams implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.accounts.Account getAccountToMigrate();
@@ -588,7 +630,7 @@
   public abstract class Context {
     method @NonNull public java.io.File getCrateDir(@NonNull String);
     method public abstract int getDisplayId();
-    method public android.os.UserHandle getUser();
+    method @NonNull public android.os.UserHandle getUser();
     method public int getUserId();
     method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
     method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
@@ -643,7 +685,7 @@
     method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
     method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
     method @Nullable public abstract String[] getNamesForUids(int[]);
-    method @NonNull public abstract String getPermissionControllerPackageName();
+    method @NonNull public String getPermissionControllerPackageName();
     method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
     method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
     method @Nullable public String getSystemTextClassifierPackageName();
@@ -1240,10 +1282,6 @@
 
 package android.net {
 
-  public class ConnectivityManager {
-    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);
-  }
-
   public class EthernetManager {
     method public void setIncludeTestInterfaces(boolean);
   }
@@ -1252,11 +1290,6 @@
     field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
   }
 
-  public final class NetworkCapabilities implements android.os.Parcelable {
-    method public int[] getCapabilities();
-    field public static final int TRANSPORT_TEST = 7; // 0x7
-  }
-
   public class NetworkStack {
     method public static void setServiceForTest(@Nullable android.os.IBinder);
   }
@@ -1615,6 +1648,7 @@
     field public static final String APP_OPS_CONSTANTS = "app_ops_constants";
     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";
     field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
     field public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
     field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
diff --git a/core/java/android/annotation/MainThread.java b/core/java/android/annotation/MainThread.java
index 556fdb4..a070246 100644
--- a/core/java/android/annotation/MainThread.java
+++ b/core/java/android/annotation/MainThread.java
@@ -21,8 +21,6 @@
 import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
-import android.os.Looper;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
@@ -40,8 +38,7 @@
  * </code>
  * </pre>
  *
- * @memberDoc This method must be called from the
- *            {@linkplain Looper#getMainLooper() main thread} of your app.
+ * @memberDoc This method must be called from the main thread of your app.
  * @hide
  */
 @Retention(SOURCE)
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index bbda871..5b0ad22 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -31,7 +31,7 @@
 import android.app.job.JobSchedulerFrameworkInitializer;
 import android.app.people.PeopleManager;
 import android.app.prediction.AppPredictionManager;
-import android.app.role.RoleManager;
+import android.app.role.RoleFrameworkInitializer;
 import android.app.search.SearchUiManager;
 import android.app.slice.SliceManager;
 import android.app.time.TimeManager;
@@ -1320,14 +1320,6 @@
                                 ctx.getMainThreadHandler());
                     }});
 
-        registerService(Context.ROLE_SERVICE, RoleManager.class,
-                new CachedServiceFetcher<RoleManager>() {
-                    @Override
-                    public RoleManager createService(ContextImpl ctx)
-                            throws ServiceNotFoundException {
-                        return new RoleManager(ctx.getOuterContext());
-                    }});
-
         registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class,
                 new CachedServiceFetcher<DynamicSystemManager>() {
                     @Override
@@ -1423,6 +1415,7 @@
             RollbackManagerFrameworkInitializer.initialize();
             MediaFrameworkPlatformInitializer.registerServiceWrappers();
             MediaFrameworkInitializer.registerServiceWrappers();
+            RoleFrameworkInitializer.registerServiceWrappers();
         } finally {
             // If any of the above code throws, we're in a pretty bad shape and the process
             // will likely crash, but we'll reset it just in case there's an exception handler...
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d5ffa4f..530cfd5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -88,6 +88,7 @@
 import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.net.NetworkUtilsInternal;
@@ -148,6 +149,7 @@
  */
 @SystemService(Context.DEVICE_POLICY_SERVICE)
 @RequiresFeature(PackageManager.FEATURE_DEVICE_ADMIN)
+@SuppressLint("UseIcu")
 public class DevicePolicyManager {
 
     private static String TAG = "DevicePolicyManager";
@@ -1992,6 +1994,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_OK = 0;
 
     /**
@@ -2003,6 +2006,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_HAS_DEVICE_OWNER = 1;
 
     /**
@@ -2014,6 +2018,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_USER_HAS_PROFILE_OWNER = 2;
 
     /**
@@ -2024,6 +2029,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_USER_NOT_RUNNING = 3;
 
     /**
@@ -2035,6 +2041,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_USER_SETUP_COMPLETED = 4;
 
     /**
@@ -2042,6 +2049,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_NONSYSTEM_USER_EXISTS = 5;
 
     /**
@@ -2049,6 +2057,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_ACCOUNTS_NOT_EMPTY = 6;
 
     /**
@@ -2059,6 +2068,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_NOT_SYSTEM_USER = 7;
 
     /**
@@ -2070,6 +2080,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_HAS_PAIRED = 8;
 
     /**
@@ -2081,6 +2092,7 @@
      * @see {@link PackageManager#FEATURE_MANAGED_USERS}
      * @hide
      */
+    @TestApi
     public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9;
 
     /**
@@ -2092,6 +2104,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_SYSTEM_USER = 10;
 
     /**
@@ -2102,6 +2115,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11;
 
     /**
@@ -2114,6 +2128,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12;
 
     /**
@@ -2121,11 +2136,12 @@
      *
      * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
      * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do no support device
+     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do not support device
      * admins.
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_DEVICE_ADMIN_NOT_SUPPORTED = 13;
 
     /**
@@ -2137,9 +2153,21 @@
      *
      * @hide
      */
+    @TestApi
     public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14;
 
     /**
+     * Result code for {@link #checkProvisioningPreCondition}.
+     *
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} on devices which do not support provisioning.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15;
+
+    /**
      * Result codes for {@link #checkProvisioningPreCondition} indicating all the provisioning pre
      * conditions.
      *
@@ -2151,12 +2179,14 @@
             CODE_USER_SETUP_COMPLETED, CODE_NOT_SYSTEM_USER, CODE_HAS_PAIRED,
             CODE_MANAGED_USERS_NOT_SUPPORTED, CODE_SYSTEM_USER, CODE_CANNOT_ADD_MANAGED_PROFILE,
             CODE_NOT_SYSTEM_USER_SPLIT, CODE_DEVICE_ADMIN_NOT_SUPPORTED,
-            CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER
+            CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER,
+            CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS
     })
     public @interface ProvisioningPreCondition {}
 
     /**
-     * Service-specific error code for {@link #createAndProvisionManagedProfile}:
+     * Service-specific error code for {@link #provisionFullyManagedDevice} and
+     * {@link #createAndProvisionManagedProfile}:
      * Indicates the call to {@link #checkProvisioningPreCondition} returned an error code.
      *
      * @hide
@@ -2202,8 +2232,26 @@
     public static final int PROVISIONING_RESULT_STARTING_PROFILE_FAILED = 5;
 
     /**
-     * Service-specific error codes for {@link #createAndProvisionManagedProfile} indicating
-     * all the errors during provisioning.
+     * Service-specific error code for {@link #provisionFullyManagedDevice}:
+     * Indicates that removing the non required apps have failed.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final int PROVISIONING_RESULT_REMOVE_NON_REQUIRED_APPS_FAILED = 6;
+
+    /**
+     * Service-specific error code for {@link #provisionFullyManagedDevice}:
+     * Indicates the call to {@link #setDeviceOwner} returned {@code false}.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final int PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED = 7;
+
+    /**
+     * Service-specific error codes for {@link #createAndProvisionManagedProfile} and
+     * {@link #provisionFullyManagedDevice} indicating all the errors during provisioning.
      *
      * @hide
      */
@@ -2212,7 +2260,9 @@
             PROVISIONING_RESULT_PRE_CONDITION_FAILED, PROVISIONING_RESULT_PROFILE_CREATION_FAILED,
             PROVISIONING_RESULT_ADMIN_PACKAGE_INSTALLATION_FAILED,
             PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED,
-            PROVISIONING_RESULT_STARTING_PROFILE_FAILED
+            PROVISIONING_RESULT_STARTING_PROFILE_FAILED,
+            PROVISIONING_RESULT_REMOVE_NON_REQUIRED_APPS_FAILED,
+            PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED
     })
     public @interface ProvisioningResult {}
 
@@ -5276,30 +5326,10 @@
                     if (!proxySpec.type().equals(Proxy.Type.HTTP)) {
                         throw new IllegalArgumentException();
                     }
-                    InetSocketAddress sa = (InetSocketAddress)proxySpec.address();
-                    String hostName = sa.getHostName();
-                    int port = sa.getPort();
-                    StringBuilder hostBuilder = new StringBuilder();
-                    hostSpec = hostBuilder.append(hostName)
-                        .append(":").append(Integer.toString(port)).toString();
-                    if (exclusionList == null) {
-                        exclSpec = "";
-                    } else {
-                        StringBuilder listBuilder = new StringBuilder();
-                        boolean firstDomain = true;
-                        for (String exclDomain : exclusionList) {
-                            if (!firstDomain) {
-                                listBuilder = listBuilder.append(",");
-                            } else {
-                                firstDomain = false;
-                            }
-                            listBuilder = listBuilder.append(exclDomain.trim());
-                        }
-                        exclSpec = listBuilder.toString();
-                    }
-                    if (android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec)
-                            != android.net.Proxy.PROXY_VALID)
-                        throw new IllegalArgumentException();
+                    final Pair<String, String> proxyParams =
+                            getProxyParameters(proxySpec, exclusionList);
+                    hostSpec = proxyParams.first;
+                    exclSpec = proxyParams.second;
                 }
                 return mService.setGlobalProxy(admin, hostSpec, exclSpec);
             } catch (RemoteException e) {
@@ -5310,6 +5340,41 @@
     }
 
     /**
+     * Build HTTP proxy parameters for {@link IDevicePolicyManager#setGlobalProxy}.
+     * @throws IllegalArgumentException Invalid proxySpec
+     * @hide
+     */
+    @VisibleForTesting
+    public Pair<String, String> getProxyParameters(Proxy proxySpec, List<String> exclusionList) {
+        InetSocketAddress sa = (InetSocketAddress) proxySpec.address();
+        String hostName = sa.getHostName();
+        int port = sa.getPort();
+        StringBuilder hostBuilder = new StringBuilder();
+        final String hostSpec = hostBuilder.append(hostName)
+                .append(":").append(Integer.toString(port)).toString();
+        final String exclSpec;
+        if (exclusionList == null) {
+            exclSpec = "";
+        } else {
+            StringBuilder listBuilder = new StringBuilder();
+            boolean firstDomain = true;
+            for (String exclDomain : exclusionList) {
+                if (!firstDomain) {
+                    listBuilder = listBuilder.append(",");
+                } else {
+                    firstDomain = false;
+                }
+                listBuilder = listBuilder.append(exclDomain.trim());
+            }
+            exclSpec = listBuilder.toString();
+        }
+        if (android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec)
+                != android.net.Proxy.PROXY_VALID) throw new IllegalArgumentException();
+
+        return new Pair<>(hostSpec, exclSpec);
+    }
+
+    /**
      * Set a network-independent global HTTP proxy. This is not normally what you want for typical
      * HTTP proxies - they are generally network dependent. However if you're doing something
      * unusual like general internal filtering this may be useful. On a private network where the
@@ -5444,6 +5509,16 @@
             "android.app.action.ACTION_SHOW_NEW_USER_DISCLAIMER";
 
     /**
+     * Broadcast action: notify managed provisioning that the device has been provisioned.
+     *
+     * @hide
+     */
+    @TestApi
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PROVISIONED_MANAGED_DEVICE =
+            "android.app.action.PROVISIONED_MANAGED_DEVICE";
+
+    /**
      * Broadcast action: notify managed provisioning that a new managed profile is created.
      *
      * @hide
@@ -10669,8 +10744,9 @@
      * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed.
      * @hide
      */
+    @TestApi
     public @ProvisioningPreCondition int checkProvisioningPreCondition(
-            String action, @NonNull String packageName) {
+            @Nullable String action, @NonNull String packageName) {
         try {
             return mService.checkProvisioningPreCondition(action, packageName);
         } catch (RemoteException re) {
@@ -13206,4 +13282,36 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Provisions a managed device and sets the {@code deviceAdminComponentName} as the device
+     * owner.
+     *
+     * <p>The method {@link #checkProvisioningPreCondition} must be returning {@link #CODE_OK}
+     * before calling this method.
+     *
+     * @param provisioningParams Params required to provision a fully managed device,
+     * see {@link FullyManagedDeviceProvisioningParams}.
+     *
+     * @throws SecurityException if the caller does not hold
+     * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}.
+     * @throws ProvisioningException if an error occurred during provisioning.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+    public void provisionFullyManagedDevice(
+            @NonNull FullyManagedDeviceProvisioningParams provisioningParams)
+            throws ProvisioningException {
+        if (mService != null) {
+            try {
+                mService.provisionFullyManagedDevice(provisioningParams);
+            } catch (ServiceSpecificException e) {
+                throw new ProvisioningException(e, e.errorCode);
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.aidl b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.aidl
new file mode 100644
index 0000000..8a9cbba
--- /dev/null
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.aidl
@@ -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.
+ */
+
+package android.app.admin;
+
+parcelable FullyManagedDeviceProvisioningParams;
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
new file mode 100644
index 0000000..83af019
--- /dev/null
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
@@ -0,0 +1,253 @@
+/*
+ * 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.admin;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Params required to provision a fully managed device, see
+ * {@link DevicePolicyManager#provisionFullyManagedDevice}.
+ * @hide
+ */
+@TestApi
+public final class FullyManagedDeviceProvisioningParams implements Parcelable {
+    @NonNull private final ComponentName mDeviceAdminComponentName;
+    @NonNull private final String mOwnerName;
+    private final boolean mLeaveAllSystemAppsEnabled;
+    @Nullable private final String mTimeZone;
+    private final long mLocalTime;
+    @SuppressLint("UseIcu")
+    @Nullable private final Locale mLocale;
+
+    private FullyManagedDeviceProvisioningParams(
+            @NonNull ComponentName deviceAdminComponentName,
+            @NonNull String ownerName,
+            boolean leaveAllSystemAppsEnabled,
+            @Nullable String timeZone,
+            long localTime,
+            @Nullable @SuppressLint("UseIcu") Locale locale) {
+        this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
+        this.mOwnerName = requireNonNull(ownerName);
+        this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
+        this.mTimeZone = timeZone;
+        this.mLocalTime = localTime;
+        this.mLocale = locale;
+    }
+
+    private FullyManagedDeviceProvisioningParams(
+            @NonNull ComponentName deviceAdminComponentName,
+            @NonNull String ownerName,
+            boolean leaveAllSystemAppsEnabled,
+            @Nullable String timeZone,
+            long localTime,
+            @Nullable String localeStr) {
+        this(deviceAdminComponentName,
+                ownerName,
+                leaveAllSystemAppsEnabled,
+                timeZone,
+                localTime,
+                getLocale(localeStr));
+    }
+
+    @Nullable
+    private static Locale getLocale(String localeStr) {
+        return localeStr == null ? null : Locale.forLanguageTag(localeStr);
+    }
+
+    @NonNull
+    public ComponentName getDeviceAdminComponentName() {
+        return mDeviceAdminComponentName;
+    }
+
+    @NonNull
+    public String getOwnerName() {
+        return mOwnerName;
+    }
+
+    public boolean isLeaveAllSystemAppsEnabled() {
+        return mLeaveAllSystemAppsEnabled;
+    }
+
+    @Nullable
+    public String getTimeZone() {
+        return mTimeZone;
+    }
+
+    public long getLocalTime() {
+        return mLocalTime;
+    }
+
+    @Nullable
+    public @SuppressLint("UseIcu") Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * Builder class for {@link FullyManagedDeviceProvisioningParams} objects.
+     */
+    public static final class Builder {
+        @NonNull private final ComponentName mDeviceAdminComponentName;
+        @NonNull private final String mOwnerName;
+        private boolean mLeaveAllSystemAppsEnabled;
+        @Nullable private String mTimeZone;
+        private long mLocalTime;
+        @SuppressLint("UseIcu")
+        @Nullable private Locale mLocale;
+
+        /**
+         * Initialize a new {@link Builder} to construct a
+         * {@link FullyManagedDeviceProvisioningParams}.
+         * <p>
+         * See {@link DevicePolicyManager#provisionFullyManagedDevice}
+         *
+         * @param deviceAdminComponentName The admin {@link ComponentName} to be set as the device
+         * owner.
+         * @param ownerName The name of the device owner.
+         *
+         * @throws NullPointerException if {@code deviceAdminComponentName} or
+         * {@code ownerName} are null.
+         */
+        public Builder(
+                @NonNull ComponentName deviceAdminComponentName, @NonNull String ownerName) {
+            this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
+            this.mOwnerName = requireNonNull(ownerName);
+        }
+
+        /**
+         * Sets whether non-required system apps should be installed on
+         * the created profile when
+         * {@link DevicePolicyManager#provisionFullyManagedDevice}
+         * is called. Defaults to {@code false} if not set.
+         */
+        @NonNull
+        public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) {
+            this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
+            return this;
+        }
+
+        /**
+         * Sets {@code timeZone} on the device. If not set or set to {@code null},
+         * {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a timezone
+         */
+        @NonNull
+        public Builder setTimeZone(@Nullable String timeZone) {
+            this.mTimeZone = timeZone;
+            return this;
+        }
+
+        /**
+         * Sets {@code localTime} on the device, If not set or set to
+         * {@code 0}, {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a
+         * local time.
+         */
+        @NonNull
+        public Builder setLocalTime(long localTime) {
+            this.mLocalTime = localTime;
+            return this;
+        }
+
+        /**
+         * Sets {@link Locale} on the device, If not set or set to {@code null},
+         * {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a locale.
+         */
+        @NonNull
+        public Builder setLocale(@SuppressLint("UseIcu") @Nullable Locale locale) {
+            this.mLocale = locale;
+            return this;
+        }
+
+        /**
+         * Combines all of the attributes that have been set on this {@code Builder}
+         *
+         * @return a new {@link FullyManagedDeviceProvisioningParams} object.
+         */
+        @NonNull
+        public FullyManagedDeviceProvisioningParams build() {
+            return new FullyManagedDeviceProvisioningParams(
+                    mDeviceAdminComponentName,
+                    mOwnerName,
+                    mLeaveAllSystemAppsEnabled,
+                    mTimeZone,
+                    mLocalTime,
+                    mLocale);
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "FullyManagedDeviceProvisioningParams{"
+                + "mDeviceAdminComponentName=" + mDeviceAdminComponentName
+                + ", mOwnerName=" + mOwnerName
+                + ", mLeaveAllSystemAppsEnabled=" + mLeaveAllSystemAppsEnabled
+                + ", mTimeZone=" + (mTimeZone == null ? "null" : mTimeZone)
+                + ", mLocalTime=" + mLocalTime
+                + ", mLocale=" + (mLocale == null ? "null" : mLocale)
+                + '}';
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
+        dest.writeTypedObject(mDeviceAdminComponentName, flags);
+        dest.writeString(mOwnerName);
+        dest.writeBoolean(mLeaveAllSystemAppsEnabled);
+        dest.writeString(mTimeZone);
+        dest.writeLong(mLocalTime);
+        dest.writeString(mLocale == null ? null : mLocale.toLanguageTag());
+    }
+
+    @NonNull
+    public static final Creator<FullyManagedDeviceProvisioningParams> CREATOR =
+            new Creator<FullyManagedDeviceProvisioningParams>() {
+                @Override
+                public FullyManagedDeviceProvisioningParams createFromParcel(Parcel in) {
+                    ComponentName componentName = in.readTypedObject(ComponentName.CREATOR);
+                    String ownerName = in.readString();
+                    boolean leaveAllSystemAppsEnabled = in.readBoolean();
+                    String timeZone = in.readString();
+                    long localtime = in.readLong();
+                    String locale = in.readString();
+
+                    return new FullyManagedDeviceProvisioningParams(
+                            componentName,
+                            ownerName,
+                            leaveAllSystemAppsEnabled,
+                            timeZone,
+                            localtime,
+                            locale);
+                }
+
+                @Override
+                public FullyManagedDeviceProvisioningParams[] newArray(int size) {
+                    return new FullyManagedDeviceProvisioningParams[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index dded542..3765a67 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -26,6 +26,7 @@
 import android.app.admin.PasswordMetrics;
 import android.app.admin.FactoryResetProtectionPolicy;
 import android.app.admin.ManagedProfileProvisioningParams;
+import android.app.admin.FullyManagedDeviceProvisioningParams;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -496,4 +497,5 @@
     void setOrganizationIdForUser(in String callerPackage, in String enterpriseId, int userId);
 
     UserHandle createAndProvisionManagedProfile(in ManagedProfileProvisioningParams provisioningParams);
+    void provisionFullyManagedDevice(in FullyManagedDeviceProvisioningParams provisioningParams);
 }
diff --git a/core/java/android/app/admin/ProvisioningException.java b/core/java/android/app/admin/ProvisioningException.java
index 79a830d..639859b 100644
--- a/core/java/android/app/admin/ProvisioningException.java
+++ b/core/java/android/app/admin/ProvisioningException.java
@@ -15,15 +15,16 @@
  */
 
 package android.app.admin;
-
 import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.util.AndroidException;
 
 /**
- * Thrown to indicate a failure during {@link DevicePolicyManager#createAndProvisionManagedProfile}.
+ * Thrown to indicate a failure during {@link DevicePolicyManager#provisionFullyManagedDevice} and
+ * {@link DevicePolicyManager#createAndProvisionManagedProfile}.
  *
  * @hide
+ *
  */
 @TestApi
 public class ProvisioningException extends AndroidException {
diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java
index ba1f612..93a7ae0 100644
--- a/core/java/android/app/role/RoleControllerManager.java
+++ b/core/java/android/app/role/RoleControllerManager.java
@@ -20,15 +20,15 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
-import android.app.ActivityThread;
 import android.content.ComponentName;
 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.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.RemoteCallback;
 import android.util.Log;
 import android.util.SparseArray;
@@ -95,11 +95,10 @@
     private RoleControllerManager(@NonNull ComponentName remoteServiceComponentName,
             @NonNull Handler handler, @NonNull Context context) {
         synchronized (sRemoteServicesLock) {
-            int userId = context.getUserId();
+            int userId = context.getUser().getIdentifier();
             ServiceConnector<IRoleController> remoteService = sRemoteServices.get(userId);
             if (remoteService == null) {
-                remoteService = new ServiceConnector.Impl<IRoleController>(
-                        ActivityThread.currentApplication(),
+                remoteService = new ServiceConnector.Impl<IRoleController>(context,
                         new Intent(RoleControllerService.SERVICE_INTERFACE)
                                 .setComponent(remoteServiceComponentName),
                         0 /* bindingFlags */, userId, IRoleController.Stub::asInterface) {
@@ -119,7 +118,7 @@
      * @hide
      */
     public RoleControllerManager(@NonNull Context context) {
-        this(getRemoteServiceComponentName(context), context.getMainThreadHandler(), context);
+        this(getRemoteServiceComponentName(context), new Handler(Looper.getMainLooper()), context);
     }
 
     @NonNull
@@ -127,8 +126,8 @@
         Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE);
         PackageManager packageManager = context.getPackageManager();
         intent.setPackage(packageManager.getPermissionControllerPackageName());
-        ResolveInfo resolveInfo = packageManager.resolveService(intent, 0);
-        return resolveInfo.getComponentInfo().getComponentName();
+        ServiceInfo serviceInfo = packageManager.resolveService(intent, 0).serviceInfo;
+        return new ComponentName(serviceInfo.packageName, serviceInfo.name);
     }
 
     /**
diff --git a/core/java/android/app/role/RoleControllerService.java b/core/java/android/app/role/RoleControllerService.java
index d92c956..6ef9e44 100644
--- a/core/java/android/app/role/RoleControllerService.java
+++ b/core/java/android/app/role/RoleControllerService.java
@@ -33,7 +33,6 @@
 import android.os.UserHandle;
 
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -85,9 +84,7 @@
 
                 Objects.requireNonNull(callback, "callback cannot be null");
 
-                mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
-                        RoleControllerService::grantDefaultRoles, RoleControllerService.this,
-                        callback));
+                mWorkerHandler.post(() -> RoleControllerService.this.grantDefaultRoles(callback));
             }
 
             @Override
@@ -100,9 +97,8 @@
                         "packageName cannot be null or empty");
                 Objects.requireNonNull(callback, "callback cannot be null");
 
-                mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
-                        RoleControllerService::onAddRoleHolder, RoleControllerService.this,
-                        roleName, packageName, flags, callback));
+                mWorkerHandler.post(() -> RoleControllerService.this.onAddRoleHolder(roleName,
+                        packageName, flags, callback));
             }
 
             @Override
@@ -115,9 +111,8 @@
                         "packageName cannot be null or empty");
                 Objects.requireNonNull(callback, "callback cannot be null");
 
-                mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
-                        RoleControllerService::onRemoveRoleHolder, RoleControllerService.this,
-                        roleName, packageName, flags, callback));
+                mWorkerHandler.post(() -> RoleControllerService.this.onRemoveRoleHolder(roleName,
+                        packageName, flags, callback));
             }
 
             @Override
@@ -127,9 +122,8 @@
                 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
                 Objects.requireNonNull(callback, "callback cannot be null");
 
-                mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
-                        RoleControllerService::onClearRoleHolders, RoleControllerService.this,
-                        roleName, flags, callback));
+                mWorkerHandler.post(() -> RoleControllerService.this.onClearRoleHolders(roleName,
+                        flags, callback));
             }
 
             private void enforceCallerSystemUid(@NonNull String methodName) {
@@ -274,6 +268,7 @@
      *
      * @deprecated Implement {@link #onIsApplicationVisibleForRole(String, String)} instead.
      */
+    @Deprecated
     public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName,
             @NonNull String packageName);
 
diff --git a/core/java/android/app/role/RoleFrameworkInitializer.java b/core/java/android/app/role/RoleFrameworkInitializer.java
new file mode 100644
index 0000000..15a324f
--- /dev/null
+++ b/core/java/android/app/role/RoleFrameworkInitializer.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 android.app.role;
+
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Class holding initialization code for role in the permission module.
+ *
+ * @hide
+ */
+//@SystemApi
+public class RoleFrameworkInitializer {
+    private RoleFrameworkInitializer() {}
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers
+     * {@link RoleManager} to {@link Context}, so that {@link Context#getSystemService} can return
+     * it.
+     *
+     * <p>If this is called from other places, it throws a {@link IllegalStateException).
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(Context.ROLE_SERVICE, RoleManager.class,
+                (context, serviceBinder) -> new RoleManager(context,
+                        IRoleManager.Stub.asInterface(serviceBinder)));
+    }
+}
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 3788257..73f9c74 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -32,14 +32,12 @@
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.util.List;
 import java.util.Objects;
@@ -180,12 +178,16 @@
     private final Object mRoleControllerManagerLock = new Object();
 
     /**
+     * Create a new instance of this class.
+     *
+     * @param context the {@link Context}
+     * @param service the {@link IRoleManager} service
+     *
      * @hide
      */
-    public RoleManager(@NonNull Context context) throws ServiceManager.ServiceNotFoundException {
+    public RoleManager(@NonNull Context context, @NonNull IRoleManager service) {
         mContext = context;
-        mService = IRoleManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
-                Context.ROLE_SERVICE));
+        mService = service;
     }
 
     /**
@@ -747,9 +749,8 @@
         public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
             final long token = Binder.clearCallingIdentity();
             try {
-                mExecutor.execute(PooledLambda.obtainRunnable(
-                        OnRoleHoldersChangedListener::onRoleHoldersChanged, mListener, roleName,
-                        UserHandle.of(userId)));
+                mExecutor.execute(() ->
+                        mListener.onRoleHoldersChanged(roleName, UserHandle.of(userId)));
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/core/java/android/app/role/TEST_MAPPING b/core/java/android/app/role/TEST_MAPPING
index 11c2803..f8f140d 100644
--- a/core/java/android/app/role/TEST_MAPPING
+++ b/core/java/android/app/role/TEST_MAPPING
@@ -9,4 +9,4 @@
             ]
         }
     ]
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e4a81cf..3f7479b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5919,9 +5919,14 @@
             throws PackageManager.NameNotFoundException;
 
     /**
-     * Get the user associated with this context
+     * Get the user associated with this context.
+     *
+     * @return the user associated with this context
+     *
      * @hide
      */
+    @NonNull
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
     public UserHandle getUser() {
         return android.os.Process.myUserHandle();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 747f8dc..8243dc6 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2589,6 +2589,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device is compatible with Android’s security model.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SECURITY_MODEL_COMPATIBLE =
+            "android.hardware.security.model.compatible";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports the OpenGL ES
      * <a href="http://www.khronos.org/registry/gles/extensions/ANDROID/ANDROID_extension_pack_es31a.txt">
      * Android Extension Pack</a>.
@@ -4821,15 +4829,17 @@
     /**
      * Gets the package name of the component controlling runtime permissions.
      *
-     * @return The package name.
+     * @return the package name of the component controlling runtime permissions
      *
      * @hide
      */
-    @SuppressWarnings("HiddenAbstractMethod")
-    @UnsupportedAppUsage
     @NonNull
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public abstract String getPermissionControllerPackageName();
+    @UnsupportedAppUsage
+    public String getPermissionControllerPackageName() {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
 
     /**
      * Add a new dynamic permission to the system.  For this to work, your
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index b826b7a..38d3940 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -102,6 +102,8 @@
     public static ForInternedStringValueMap sForInternedStringValueMap =
             Parcelling.Cache.getOrCreate(ForInternedStringValueMap.class);
     public static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class);
+    public static ForInternedStringSet sForInternedStringSet =
+            Parcelling.Cache.getOrCreate(ForInternedStringSet.class);
     protected static ParsedIntentInfo.StringPairListParceler sForIntentInfoPairs =
             Parcelling.Cache.getOrCreate(ParsedIntentInfo.StringPairListParceler.class);
 
@@ -1143,6 +1145,7 @@
         dest.writeString(this.mPath);
         dest.writeParcelableList(this.queriesIntents, flags);
         sForInternedStringList.parcel(this.queriesPackages, dest, flags);
+        sForInternedStringSet.parcel(this.queriesProviders, dest, flags);
         dest.writeString(this.appComponentFactory);
         dest.writeString(this.backupAgentName);
         dest.writeInt(this.banner);
@@ -1261,6 +1264,7 @@
         this.mPath = in.readString();
         this.queriesIntents = in.createTypedArrayList(Intent.CREATOR);
         this.queriesPackages = sForInternedStringList.unparcel(in);
+        this.queriesProviders = sForInternedStringSet.unparcel(in);
         this.appComponentFactory = in.readString();
         this.backupAgentName = in.readString();
         this.banner = in.readInt();
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 421a07b..5a03ade 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -47,40 +47,28 @@
      * begins adjusting the power state to match what was requested.
      * </p>
      *
-     * @param groupId The identifier for the display group being requested to change power state
      * @param request The requested power state.
-     * @param waitForNegativeProximity If {@code true}, issues a request to wait for
+     * @param waitForNegativeProximity If true, issues a request to wait for
      * negative proximity before turning the screen back on, assuming the screen
      * was turned off by the proximity sensor.
-     * @return {@code true} if display group is ready, {@code false} if there are important
-     * changes that must be made asynchronously (such as turning the screen on), in which case
-     * the caller should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged}
-     * then try the request again later until the state converges. If the provided {@code groupId}
-     * cannot be found then {@code true} will be returned.
+     * @return True if display is ready, false if there are important changes that must
+     * be made asynchronously (such as turning the screen on), in which case the caller
+     * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
+     * then try the request again later until the state converges.
      */
-    public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request,
+    public abstract boolean requestPowerState(DisplayPowerRequest request,
             boolean waitForNegativeProximity);
 
     /**
-     * Returns {@code true} if the proximity sensor screen-off function is available.
+     * Returns true if the proximity sensor screen-off function is available.
      */
     public abstract boolean isProximitySensorAvailable();
 
     /**
-     * Registers a display group listener which will be informed of the addition, removal, or change
-     * of display groups.
-     *
-     * @param listener The listener to register.
+     * Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided
+     * display belongs.
      */
-    public abstract void registerDisplayGroupListener(DisplayGroupListener listener);
-
-    /**
-     * Unregisters a display group listener which will be informed of the addition, removal, or
-     * change of display groups.
-     *
-     * @param listener The listener to unregister.
-     */
-    public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener);
+    public abstract int getDisplayGroupId(int displayId);
 
     /**
      * Screenshot for internal system-only use such as rotation, etc.  This method includes
@@ -463,7 +451,7 @@
         void onStateChanged();
         void onProximityPositive();
         void onProximityNegative();
-        void onDisplayStateChange(boolean allInactive, boolean allOff);
+        void onDisplayStateChange(int state); // one of the Display state constants
 
         void acquireSuspendBlocker();
         void releaseSuspendBlocker();
@@ -477,33 +465,4 @@
     public interface DisplayTransactionListener {
         void onDisplayTransaction(Transaction t);
     }
-
-    /**
-     * Called when there are changes to {@link com.android.server.display.DisplayGroup
-     * DisplayGroups}.
-     */
-    public interface DisplayGroupListener {
-        /**
-         * A new display group with the provided {@code groupId} was added.
-         * This is guaranteed to be called <i>before</i> any corresponding calls to
-         * {@link android.hardware.display.DisplayManager.DisplayListener} are made.
-         */
-        void onDisplayGroupAdded(int groupId);
-
-        /**
-         * The display group with the provided {@code groupId} was removed.
-         *
-         * This is guaranteed to be called <i>after</i> any corresponding calls to
-         * {@link android.hardware.display.DisplayManager.DisplayListener} are made.
-         */
-        void onDisplayGroupRemoved(int groupId);
-
-        /**
-         * The display group with the provided {@code groupId} has changed.
-         *
-         * This is guaranteed to be called <i>after</i> any corresponding calls to
-         * {@link android.hardware.display.DisplayManager.DisplayListener} are made.
-         */
-        void onDisplayGroupChanged(int groupId);
-    }
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 899af5a..2e45ed8 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkRequest.Type.LISTEN;
 import static android.net.NetworkRequest.Type.REQUEST;
 import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
+import static android.net.QosCallback.QosCallbackRegistrationException;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
@@ -29,7 +30,6 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.TestApi;
 import android.app.PendingIntent;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -4823,6 +4823,8 @@
     /**
      * Simulates a Data Stall for the specified Network.
      *
+     * <p>This method should only be used for tests.
+     *
      * <p>The caller must be the owner of the specified Network.
      *
      * @param detectionMethod The detection method used to identify the Data Stall.
@@ -4832,7 +4834,7 @@
      * @throws SecurityException if the caller is not the owner of the given network.
      * @hide
      */
-    @TestApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS,
             android.Manifest.permission.NETWORK_STACK})
     public void simulateDataStall(int detectionMethod, long timestampMillis,
@@ -4848,4 +4850,118 @@
         Log.d(TAG, "setOemNetworkPreference called with preference: "
                 + preference.toString());
     }
+
+    @NonNull
+    private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>();
+
+    /**
+     * Registers a {@link QosSocketInfo} with an associated {@link QosCallback}.  The callback will
+     * receive available QoS events related to the {@link Network} and local ip + port
+     * specified within socketInfo.
+     * <p/>
+     * The same {@link QosCallback} must be unregistered before being registered a second time,
+     * otherwise {@link QosCallbackRegistrationException} is thrown.
+     * <p/>
+     * This API does not, in itself, require any permission if called with a network that is not
+     * restricted. However, the underlying implementation currently only supports the IMS network,
+     * which is always restricted. That means non-preinstalled callers can't possibly find this API
+     * useful, because they'd never be called back on networks that they would have access to.
+     *
+     * @throws SecurityException if {@link QosSocketInfo#getNetwork()} is restricted and the app is
+     * missing CONNECTIVITY_USE_RESTRICTED_NETWORKS permission.
+     * @throws QosCallback.QosCallbackRegistrationException if qosCallback is already registered.
+     * @throws RuntimeException if the app already has too many callbacks registered.
+     *
+     * Exceptions after the time of registration is passed through
+     * {@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.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void registerQosCallback(@NonNull final QosSocketInfo socketInfo,
+            @NonNull final QosCallback callback,
+            @CallbackExecutor @NonNull final Executor executor) {
+        Objects.requireNonNull(socketInfo, "socketInfo must be non-null");
+        Objects.requireNonNull(callback, "callback must be non-null");
+        Objects.requireNonNull(executor, "executor must be non-null");
+
+        try {
+            synchronized (mQosCallbackConnections) {
+                if (getQosCallbackConnection(callback) == null) {
+                    final QosCallbackConnection connection =
+                            new QosCallbackConnection(this, callback, executor);
+                    mQosCallbackConnections.add(connection);
+                    mService.registerQosSocketCallback(socketInfo, connection);
+                } else {
+                    Log.e(TAG, "registerQosCallback: Callback already registered");
+                    throw new QosCallbackRegistrationException();
+                }
+            }
+        } catch (final RemoteException e) {
+            Log.e(TAG, "registerQosCallback: Error while registering ", e);
+
+            // The same unregister method method is called for consistency even though nothing
+            // will be sent to the ConnectivityService since the callback was never successfully
+            // registered.
+            unregisterQosCallback(callback);
+            e.rethrowFromSystemServer();
+        } catch (final ServiceSpecificException e) {
+            Log.e(TAG, "registerQosCallback: Error while registering ", e);
+            unregisterQosCallback(callback);
+            throw convertServiceException(e);
+        }
+    }
+
+    /**
+     * Unregisters the given {@link QosCallback}.  The {@link QosCallback} will no longer receive
+     * events once unregistered and can be registered a second time.
+     * <p/>
+     * If the {@link QosCallback} does not have an active registration, it is a no-op.
+     *
+     * @param callback the callback being unregistered
+     *
+     * @hide
+     */
+    @SystemApi
+    public void unregisterQosCallback(@NonNull final QosCallback callback) {
+        Objects.requireNonNull(callback, "The callback must be non-null");
+        try {
+            synchronized (mQosCallbackConnections) {
+                final QosCallbackConnection connection = getQosCallbackConnection(callback);
+                if (connection != null) {
+                    connection.stopReceivingMessages();
+                    mService.unregisterQosCallback(connection);
+                    mQosCallbackConnections.remove(connection);
+                } else {
+                    Log.d(TAG, "unregisterQosCallback: Callback not registered");
+                }
+            }
+        } catch (final RemoteException e) {
+            Log.e(TAG, "unregisterQosCallback: Error while unregistering ", e);
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the connection related to the callback.
+     *
+     * @param callback the callback to look up
+     * @return the related connection
+     */
+    @Nullable
+    private QosCallbackConnection getQosCallbackConnection(final QosCallback callback) {
+        for (final QosCallbackConnection connection : mQosCallbackConnections) {
+            // Checking by reference here is intentional
+            if (connection.getCallback() == callback) {
+                return connection;
+            }
+        }
+        return null;
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 47c7a1a..6fecee6 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -20,6 +20,8 @@
 import android.net.ConnectionInfo;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.IConnectivityDiagnosticsCallback;
+import android.net.IQosCallback;
+import android.net.ISocketKeepaliveCallback;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkAgentConfig;
@@ -27,9 +29,9 @@
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
-import android.net.ISocketKeepaliveCallback;
 import android.net.ProxyInfo;
 import android.net.UidRange;
+import android.net.QosSocketInfo;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.INetworkActivityListener;
@@ -239,4 +241,7 @@
     void unregisterNetworkActivityListener(in INetworkActivityListener l);
 
     boolean isDefaultNetworkActive();
+
+    void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback);
+    void unregisterQosCallback(in IQosCallback callback);
 }
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index f5a5966..84a2acc 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -81,4 +81,5 @@
     void factoryReset(String subscriber);
 
     boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork);
+    boolean isUidRestrictedOnMeteredNetworks(int uid);
 }
diff --git a/core/java/android/net/IQosCallback.aidl b/core/java/android/net/IQosCallback.aidl
new file mode 100644
index 0000000..91c7575
--- /dev/null
+++ b/core/java/android/net/IQosCallback.aidl
@@ -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 android.net;
+
+import android.os.Bundle;
+import android.net.QosSession;
+import android.telephony.data.EpsBearerQosSessionAttributes;
+
+/**
+ * AIDL interface for QosCallback
+ *
+ * @hide
+ */
+oneway interface IQosCallback
+{
+     void onQosEpsBearerSessionAvailable(in QosSession session,
+        in EpsBearerQosSessionAttributes attributes);
+     void onQosSessionLost(in QosSession session);
+     void onError(in int type);
+}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 83a7d16..d22d82d 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -30,6 +30,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.telephony.data.EpsBearerQosSessionAttributes;
 import android.util.Log;
 
 import com.android.connectivity.aidl.INetworkAgent;
@@ -227,7 +228,7 @@
      */
     public static final String REDIRECT_URL_KEY = "redirect URL";
 
-     /**
+    /**
      * Sent by the NetworkAgent to ConnectivityService to indicate this network was
      * explicitly selected.  This should be sent before the NetworkInfo is marked
      * CONNECTED so it can be given special treatment at that time.
@@ -341,6 +342,24 @@
      */
     private static final int EVENT_AGENT_DISCONNECTED = BASE + 19;
 
+    /**
+     * Sent by QosCallbackTracker to {@link NetworkAgent} to register a new filter with
+     * callback.
+     *
+     * arg1 = QoS agent callback ID
+     * obj = {@link QosFilter}
+     * @hide
+     */
+    public static final int CMD_REGISTER_QOS_CALLBACK = BASE + 20;
+
+    /**
+     * Sent by QosCallbackTracker to {@link NetworkAgent} to unregister a callback.
+     *
+     * arg1 = QoS agent callback ID
+     * @hide
+     */
+    public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21;
+
     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.
@@ -520,6 +539,17 @@
                     onRemoveKeepalivePacketFilter(msg.arg1 /* slot */);
                     break;
                 }
+                case CMD_REGISTER_QOS_CALLBACK: {
+                    onQosCallbackRegistered(
+                            msg.arg1 /* QoS callback id */,
+                            (QosFilter) msg.obj /* QoS filter */);
+                    break;
+                }
+                case CMD_UNREGISTER_QOS_CALLBACK: {
+                    onQosCallbackUnregistered(
+                            msg.arg1 /* QoS callback id */);
+                    break;
+                }
             }
         }
     }
@@ -553,6 +583,8 @@
     }
 
     private static class NetworkAgentBinder extends INetworkAgent.Stub {
+        private static final String LOG_TAG = NetworkAgentBinder.class.getSimpleName();
+
         private final Handler mHandler;
 
         private NetworkAgentBinder(Handler handler) {
@@ -639,6 +671,25 @@
             mHandler.sendMessage(mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER,
                     slot, 0));
         }
+
+        @Override
+        public void onQosFilterCallbackRegistered(final int qosCallbackId,
+                final QosFilterParcelable qosFilterParcelable) {
+            if (qosFilterParcelable.getQosFilter() != null) {
+                mHandler.sendMessage(
+                        mHandler.obtainMessage(CMD_REGISTER_QOS_CALLBACK, qosCallbackId, 0,
+                                qosFilterParcelable.getQosFilter()));
+                return;
+            }
+
+            Log.wtf(LOG_TAG, "onQosFilterCallbackRegistered: qos filter is null.");
+        }
+
+        @Override
+        public void onQosCallbackUnregistered(final int qosCallbackId) {
+            mHandler.sendMessage(mHandler.obtainMessage(
+                    CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null));
+        }
     }
 
     /**
@@ -1067,8 +1118,68 @@
     protected void preventAutomaticReconnect() {
     }
 
+    /**
+     * Called when a qos callback is registered with a filter.
+     * @param qosCallbackId the id for the callback registered
+     * @param filter the filter being registered
+     */
+    public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) {
+    }
+
+    /**
+     * Called when a qos callback is registered with a filter.
+     * <p/>
+     * Any QoS events that are sent with the same callback id after this method is called
+     * are a no-op.
+     *
+     * @param qosCallbackId the id for the callback being unregistered
+     */
+    public void onQosCallbackUnregistered(final int qosCallbackId) {
+    }
+
+
+    /**
+     * Sends the attributes of Eps Bearer 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
+     */
+    public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
+            @NonNull final EpsBearerQosSessionAttributes attributes) {
+        Objects.requireNonNull(attributes, "The attributes must be non-null");
+        queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
+                new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
+                attributes));
+    }
+
+    /**
+     * Sends event that the Eps 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
+     */
+    public final void sendQosSessionLost(final int qosCallbackId, final int sessionId) {
+        queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
+                new QosSession(sessionId, QosSession.TYPE_EPS_BEARER)));
+    }
+
+    /**
+     * Sends the exception type back to the application.
+     *
+     * The NetworkAgent should not send anymore messages with this id.
+     *
+     * @param qosCallbackId the callback id this exception belongs to
+     * @param exceptionType the type of exception
+     */
+    public final void sendQosCallbackError(final int qosCallbackId,
+            @QosCallbackException.ExceptionType final int exceptionType) {
+        queueOrSendMessage(ra -> ra.sendQosCallbackError(qosCallbackId, exceptionType));
+    }
+
+
     /** @hide */
-    protected void log(String s) {
+    protected void log(final String s) {
         Log.d(LOG_TAG, "NetworkAgent: " + s);
     }
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 2d9f6d8..0a895b9 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -23,7 +23,6 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.os.Build;
@@ -576,7 +575,6 @@
      * @hide
      */
     @UnsupportedAppUsage
-    @TestApi
     public @NetCapability int[] getCapabilities() {
         return BitUtils.unpackBits(mNetworkCapabilities);
     }
@@ -821,7 +819,7 @@
      *
      * @hide
      */
-    @TestApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int TRANSPORT_TEST = 7;
 
     /** @hide */
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 8728dbf..ed169e7 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -464,6 +464,22 @@
     }
 
     /**
+     * Check that the given uid is restricted from doing networking on metered networks.
+     *
+     * @param uid The target uid.
+     * @return true if the given uid is restricted from doing networking on metered networks.
+     *
+     * @hide
+     */
+    public boolean isUidRestrictedOnMeteredNetworks(int uid) {
+        try {
+            return mService.isUidRestrictedOnMeteredNetworks(uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Get multipath preference for the given network.
      */
     public int getMultipathPreference(Network network) {
diff --git a/core/java/android/net/NetworkReleasedException.java b/core/java/android/net/NetworkReleasedException.java
new file mode 100644
index 0000000..0629b75
--- /dev/null
+++ b/core/java/android/net/NetworkReleasedException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.annotation.SystemApi;
+
+/**
+ * Indicates that the {@link Network} was released and is no longer available.
+ *
+ * @hide
+ */
+@SystemApi
+public class NetworkReleasedException extends Exception {
+    /** @hide */
+    public NetworkReleasedException() {
+        super("The network was released and is no longer available");
+    }
+}
diff --git a/core/java/android/net/QosCallback.java b/core/java/android/net/QosCallback.java
new file mode 100644
index 0000000..22f06bc
--- /dev/null
+++ b/core/java/android/net/QosCallback.java
@@ -0,0 +1,91 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Receives Qos information given a {@link Network}.  The callback is registered with
+ * {@link ConnectivityManager#registerQosCallback}.
+ *
+ * <p>
+ * <br/>
+ * The callback will no longer receive calls if any of the following takes place:
+ * <ol>
+ * <li>{@link ConnectivityManager#unregisterQosCallback(QosCallback)} is called with the same
+ * callback instance.</li>
+ * <li>{@link QosCallback#onError(QosCallbackException)} is called.</li>
+ * <li>A network specific issue occurs.  eg. Congestion on a carrier network.</li>
+ * <li>The network registered with the callback has no associated QoS providers</li>
+ * </ul>
+ * {@hide}
+ */
+@SystemApi
+public abstract class QosCallback {
+    /**
+     * Invoked after an error occurs on a registered callback.  Once called, the callback is
+     * automatically unregistered and the callback will no longer receive calls.
+     *
+     * <p>The underlying exception can either be a runtime exception or a custom exception made for
+     * {@link QosCallback}. see: {@link QosCallbackException}.
+     *
+     * @param exception wraps the underlying cause
+     */
+    public void onError(@NonNull final QosCallbackException exception) {
+    }
+
+    /**
+     * Called when a Qos Session first becomes available to the callback or if its attributes have
+     * changed.
+     * <p>
+     * Note: The callback may be called multiple times with the same attributes.
+     *
+     * @param session the available session
+     * @param sessionAttributes the attributes of the session
+     */
+    public void onQosSessionAvailable(@NonNull final QosSession session,
+            @NonNull final QosSessionAttributes sessionAttributes) {
+    }
+
+    /**
+     * Called after a Qos Session is lost.
+     * <p>
+     * At least one call to
+     * {@link QosCallback#onQosSessionAvailable(QosSession, QosSessionAttributes)}
+     * with the same {@link QosSession} will precede a call to lost.
+     *
+     * @param session the lost session
+     */
+    public void onQosSessionLost(@NonNull final QosSession session) {
+    }
+
+    /**
+     * Thrown when there is a problem registering {@link QosCallback} with
+     * {@link ConnectivityManager#registerQosCallback(QosSocketInfo, QosCallback, Executor)}.
+     */
+    public static class QosCallbackRegistrationException extends RuntimeException {
+        /**
+         * @hide
+         */
+        public QosCallbackRegistrationException() {
+            super();
+        }
+    }
+}
diff --git a/core/java/android/net/QosCallbackConnection.java b/core/java/android/net/QosCallbackConnection.java
new file mode 100644
index 0000000..bdb4ad6
--- /dev/null
+++ b/core/java/android/net/QosCallbackConnection.java
@@ -0,0 +1,128 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.telephony.data.EpsBearerQosSessionAttributes;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Sends messages from {@link com.android.server.ConnectivityService} to the registered
+ * {@link QosCallback}.
+ * <p/>
+ * This is a satellite class of {@link ConnectivityManager} and not meant
+ * to be used in other contexts.
+ *
+ * @hide
+ */
+class QosCallbackConnection extends android.net.IQosCallback.Stub {
+
+    @NonNull private final ConnectivityManager mConnectivityManager;
+    @Nullable private volatile QosCallback mCallback;
+    @NonNull private final Executor mExecutor;
+
+    @VisibleForTesting
+    @Nullable
+    public QosCallback getCallback() {
+        return mCallback;
+    }
+
+    /**
+     * The constructor for the connection
+     *
+     * @param connectivityManager the mgr that created this connection
+     * @param callback the callback to send messages back to
+     * @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.
+     */
+    QosCallbackConnection(@NonNull final ConnectivityManager connectivityManager,
+            @NonNull final QosCallback callback,
+            @NonNull final Executor executor) {
+        mConnectivityManager = Objects.requireNonNull(connectivityManager,
+                "connectivityManager must be non-null");
+        mCallback = Objects.requireNonNull(callback, "callback must be non-null");
+        mExecutor = Objects.requireNonNull(executor, "executor must be non-null");
+    }
+
+    /**
+     * Called when either the {@link EpsBearerQosSessionAttributes} 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 onQosEpsBearerSessionAvailable(@NonNull final QosSession session,
+            @NonNull final EpsBearerQosSessionAttributes 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
+     */
+    @Override
+    public void onQosSessionLost(@NonNull final QosSession session) {
+        mExecutor.execute(() -> {
+            final QosCallback callback = mCallback;
+            if (callback != null) {
+                callback.onQosSessionLost(session);
+            }
+        });
+    }
+
+    /**
+     * Called when there is an error on the registered callback.
+     *
+     *  @param errorType the type of error
+     */
+    @Override
+    public void onError(@QosCallbackException.ExceptionType final int errorType) {
+        mExecutor.execute(() -> {
+            final QosCallback callback = mCallback;
+            if (callback != null) {
+                // Messages no longer need to be received since there was an error.
+                stopReceivingMessages();
+                mConnectivityManager.unregisterQosCallback(callback);
+                callback.onError(QosCallbackException.createException(errorType));
+            }
+        });
+    }
+
+    /**
+     * The callback will stop receiving messages.
+     * <p/>
+     * There are no synchronization guarantees on exactly when the callback will stop receiving
+     * messages.
+     */
+    void stopReceivingMessages() {
+        mCallback = null;
+    }
+}
diff --git a/core/java/android/net/QosCallbackException.java b/core/java/android/net/QosCallbackException.java
new file mode 100644
index 0000000..7fd9a527e
--- /dev/null
+++ b/core/java/android/net/QosCallbackException.java
@@ -0,0 +1,110 @@
+/*
+ * 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.net;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is the exception type passed back through the onError method on {@link QosCallback}.
+ * {@link QosCallbackException#getCause()} contains the actual error that caused this exception.
+ *
+ * The possible exception types as causes are:
+ * 1. {@link NetworkReleasedException}
+ * 2. {@link SocketNotBoundException}
+ * 3. {@link UnsupportedOperationException}
+ * 4. {@link SocketLocalAddressChangedException}
+ *
+ * @hide
+ */
+@SystemApi
+public final class QosCallbackException extends Exception {
+
+    /** @hide */
+    @IntDef(prefix = {"EX_TYPE_"}, value = {
+            EX_TYPE_FILTER_NONE,
+            EX_TYPE_FILTER_NETWORK_RELEASED,
+            EX_TYPE_FILTER_SOCKET_NOT_BOUND,
+            EX_TYPE_FILTER_NOT_SUPPORTED,
+            EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ExceptionType {}
+
+    private static final String TAG = "QosCallbackException";
+
+    // Types of exceptions supported //
+    /** {@hide} */
+    public static final int EX_TYPE_FILTER_NONE = 0;
+
+    /** {@hide} */
+    public static final int EX_TYPE_FILTER_NETWORK_RELEASED = 1;
+
+    /** {@hide} */
+    public static final int EX_TYPE_FILTER_SOCKET_NOT_BOUND = 2;
+
+    /** {@hide} */
+    public static final int EX_TYPE_FILTER_NOT_SUPPORTED = 3;
+
+    /** {@hide} */
+    public static final int EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED = 4;
+
+    /**
+     * Creates exception based off of a type and message.  Not all types of exceptions accept a
+     * custom message.
+     *
+     * {@hide}
+     */
+    @NonNull
+    static QosCallbackException createException(@ExceptionType final int type) {
+        switch (type) {
+            case EX_TYPE_FILTER_NETWORK_RELEASED:
+                return new QosCallbackException(new NetworkReleasedException());
+            case EX_TYPE_FILTER_SOCKET_NOT_BOUND:
+                return new QosCallbackException(new SocketNotBoundException());
+            case EX_TYPE_FILTER_NOT_SUPPORTED:
+                return new QosCallbackException(new UnsupportedOperationException(
+                        "This device does not support the specified filter"));
+            case EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED:
+                return new QosCallbackException(
+                        new SocketLocalAddressChangedException());
+            default:
+                Log.wtf(TAG, "create: No case setup for exception type: '" + type + "'");
+                return new QosCallbackException(
+                        new RuntimeException("Unknown exception code: " + type));
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public QosCallbackException(@NonNull final String message) {
+        super(message);
+    }
+
+    /**
+     * @hide
+     */
+    public QosCallbackException(@NonNull final Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/core/java/android/net/QosFilter.java b/core/java/android/net/QosFilter.java
new file mode 100644
index 0000000..0705468
--- /dev/null
+++ b/core/java/android/net/QosFilter.java
@@ -0,0 +1,62 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Provides the related filtering logic to the {@link NetworkAgent} to match {@link QosSession}s
+ * to their related {@link QosCallback}.
+ *
+ * Used by the {@link com.android.server.ConnectivityService} to validate a {@link QosCallback}
+ * is still able to receive a {@link QosSession}.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class QosFilter {
+
+    /**
+     * The constructor is kept hidden from outside this package to ensure that all derived types
+     * are known and properly handled when being passed to and from {@link NetworkAgent}.
+     *
+     * @hide
+     */
+    QosFilter() {
+    }
+
+    /**
+     * The network used with this filter.
+     *
+     * @return the registered {@link Network}
+     */
+    @NonNull
+    public abstract Network getNetwork();
+
+    /**
+     * Validates that conditions have not changed such that no further {@link QosSession}s should
+     * be passed back to the {@link QosCallback} associated to this filter.
+     *
+     * @return the error code when present, otherwise the filter is valid
+     *
+     * @hide
+     */
+    @QosCallbackException.ExceptionType
+    public abstract int validate();
+}
+
diff --git a/core/java/android/net/QosFilterParcelable.aidl b/core/java/android/net/QosFilterParcelable.aidl
new file mode 100644
index 0000000..312d635
--- /dev/null
+++ b/core/java/android/net/QosFilterParcelable.aidl
@@ -0,0 +1,21 @@
+/*
+**
+** 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.net;
+
+parcelable QosFilterParcelable;
+
diff --git a/core/java/android/net/QosFilterParcelable.java b/core/java/android/net/QosFilterParcelable.java
new file mode 100644
index 0000000..da3b2cf
--- /dev/null
+++ b/core/java/android/net/QosFilterParcelable.java
@@ -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 android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * Aware of how to parcel different types of {@link QosFilter}s.  Any new type of qos filter must
+ * have a specialized case written here.
+ * <p/>
+ * Specifically leveraged when transferring {@link QosFilter} from
+ * {@link com.android.server.ConnectivityService} to {@link NetworkAgent} when the filter is first
+ * registered.
+ * <p/>
+ * This is not meant to be used in other contexts.
+ *
+ * @hide
+ */
+public final class QosFilterParcelable implements Parcelable {
+
+    private static final String LOG_TAG = QosFilterParcelable.class.getSimpleName();
+
+    // Indicates that the filter was not successfully written to the parcel.
+    private static final int NO_FILTER_PRESENT = 0;
+
+    // The parcel is of type qos socket filter.
+    private static final int QOS_SOCKET_FILTER = 1;
+
+    private final QosFilter mQosFilter;
+
+    /**
+     * The underlying qos filter.
+     * <p/>
+     * Null only in the case parceling failed.
+     */
+    @Nullable
+    public QosFilter getQosFilter() {
+        return mQosFilter;
+    }
+
+    public QosFilterParcelable(@NonNull final QosFilter qosFilter) {
+        Objects.requireNonNull(qosFilter, "qosFilter must be non-null");
+
+        // NOTE: Normally a type check would belong here, but doing so breaks unit tests that rely
+        // on mocking qos filter.
+        mQosFilter = qosFilter;
+    }
+
+    private QosFilterParcelable(final Parcel in) {
+        final int filterParcelType = in.readInt();
+
+        switch (filterParcelType) {
+            case QOS_SOCKET_FILTER: {
+                mQosFilter = new QosSocketFilter(QosSocketInfo.CREATOR.createFromParcel(in));
+                break;
+            }
+
+            case NO_FILTER_PRESENT:
+            default: {
+                mQosFilter = null;
+            }
+        }
+    }
+
+    public static final Creator<QosFilterParcelable> CREATOR = new Creator<QosFilterParcelable>() {
+        @Override
+        public QosFilterParcelable createFromParcel(final Parcel in) {
+            return new QosFilterParcelable(in);
+        }
+
+        @Override
+        public QosFilterParcelable[] newArray(final int size) {
+            return new QosFilterParcelable[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(final Parcel dest, final int flags) {
+        if (mQosFilter instanceof QosSocketFilter) {
+            dest.writeInt(QOS_SOCKET_FILTER);
+            final QosSocketFilter qosSocketFilter = (QosSocketFilter) mQosFilter;
+            qosSocketFilter.getQosSocketInfo().writeToParcel(dest, 0);
+            return;
+        }
+        dest.writeInt(NO_FILTER_PRESENT);
+        Log.e(LOG_TAG, "Parceling failed, unknown type of filter present: " + mQosFilter);
+    }
+}
diff --git a/core/java/android/net/QosSession.aidl b/core/java/android/net/QosSession.aidl
new file mode 100644
index 0000000..c2cf366
--- /dev/null
+++ b/core/java/android/net/QosSession.aidl
@@ -0,0 +1,21 @@
+/*
+**
+** 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.net;
+
+parcelable QosSession;
+
diff --git a/core/java/android/net/QosSession.java b/core/java/android/net/QosSession.java
new file mode 100644
index 0000000..4f3bb77
--- /dev/null
+++ b/core/java/android/net/QosSession.java
@@ -0,0 +1,136 @@
+/*
+ * 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.net;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Provides identifying information of a QoS session.  Sent to an application through
+ * {@link QosCallback}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class QosSession implements Parcelable {
+
+    /**
+     * The {@link QosSession} is a LTE EPS Session.
+     */
+    public static final int TYPE_EPS_BEARER = 1;
+
+    private final int mSessionId;
+
+    private final int mSessionType;
+
+    /**
+     * Gets the unique id of the session that is used to differentiate sessions across different
+     * types.
+     * <p/>
+     * Note: Different qos sessions can be provided by different actors.
+     *
+     * @return the unique id
+     */
+    public long getUniqueId() {
+        return (long) mSessionType << 32 | mSessionId;
+    }
+
+    /**
+     * Gets the session id that is unique within that type.
+     * <p/>
+     * Note: The session id is set by the actor providing the qos.  It can be either manufactured by
+     * the actor, but also may have a particular meaning within that type.  For example, using the
+     * bearer id as the session id for {@link android.telephony.data.EpsBearerQosSessionAttributes}
+     * is a straight forward way to keep the sessions unique from one another within that type.
+     *
+     * @return the id of the session
+     */
+    public int getSessionId() {
+        return mSessionId;
+    }
+
+    /**
+     * Gets the type of session.
+     */
+    @QosSessionType
+    public int getSessionType() {
+        return mSessionType;
+    }
+
+    /**
+     * Creates a {@link QosSession}.
+     *
+     * @param sessionId uniquely identifies the session across all sessions of the same type
+     * @param sessionType the type of session
+     */
+    public QosSession(final int sessionId, @QosSessionType final int sessionType) {
+        //Ensures the session id is unique across types of sessions
+        mSessionId = sessionId;
+        mSessionType = sessionType;
+    }
+
+
+    @Override
+    public String toString() {
+        return "QosSession{"
+                + "mSessionId=" + mSessionId
+                + ", mSessionType=" + mSessionType
+                + '}';
+    }
+
+    /**
+     * Annotations for types of qos sessions.
+     */
+    @IntDef(value = {
+            TYPE_EPS_BEARER,
+    })
+    @interface QosSessionType {}
+
+    private QosSession(final Parcel in) {
+        mSessionId = in.readInt();
+        mSessionType = in.readInt();
+    }
+
+    @NonNull
+    public static final Creator<QosSession> CREATOR = new Creator<QosSession>() {
+        @NonNull
+        @Override
+        public QosSession createFromParcel(@NonNull final Parcel in) {
+            return new QosSession(in);
+        }
+
+        @NonNull
+        @Override
+        public QosSession[] newArray(final int size) {
+            return new QosSession[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull final Parcel dest, final int flags) {
+        dest.writeInt(mSessionId);
+        dest.writeInt(mSessionType);
+    }
+}
diff --git a/core/java/android/net/QosSessionAttributes.java b/core/java/android/net/QosSessionAttributes.java
new file mode 100644
index 0000000..7a88594
--- /dev/null
+++ b/core/java/android/net/QosSessionAttributes.java
@@ -0,0 +1,30 @@
+/*
+ * 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.net;
+
+import android.annotation.SystemApi;
+
+/**
+ * Implemented by classes that encapsulate Qos related attributes that describe a Qos Session.
+ *
+ * Use the instanceof keyword to determine the underlying type.
+ *
+ * @hide
+ */
+@SystemApi
+public interface QosSessionAttributes {
+}
diff --git a/core/java/android/net/QosSocketFilter.java b/core/java/android/net/QosSocketFilter.java
new file mode 100644
index 0000000..f51a088
--- /dev/null
+++ b/core/java/android/net/QosSocketFilter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.net;
+
+import static android.net.QosCallbackException.EX_TYPE_FILTER_NONE;
+import static android.net.QosCallbackException.EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.Objects;
+
+/**
+ * Filters a {@link QosSession} according to the binding on the provided {@link Socket}.
+ *
+ * @hide
+ */
+public class QosSocketFilter extends QosFilter {
+
+    private static final String TAG = QosSocketFilter.class.getSimpleName();
+
+    @NonNull
+    private final QosSocketInfo mQosSocketInfo;
+
+    /**
+     * Creates a {@link QosSocketFilter} based off of {@link QosSocketInfo}.
+     *
+     * @param qosSocketInfo the information required to filter and validate
+     */
+    public QosSocketFilter(@NonNull final QosSocketInfo qosSocketInfo) {
+        Objects.requireNonNull(qosSocketInfo, "qosSocketInfo must be non-null");
+        mQosSocketInfo = qosSocketInfo;
+    }
+
+    /**
+     * Gets the parcelable qos socket info that was used to create the filter.
+     */
+    @NonNull
+    public QosSocketInfo getQosSocketInfo() {
+        return mQosSocketInfo;
+    }
+
+    /**
+     * Performs two validations:
+     * 1. If the socket is not bound, then return
+     *    {@link QosCallbackException.EX_TYPE_FILTER_SOCKET_NOT_BOUND}. This is detected
+     *    by checking the local address on the filter which becomes null when the socket is no
+     *    longer bound.
+     * 2. In the scenario that the socket is now bound to a different local address, which can
+     *    happen in the case of UDP, then
+     *    {@link QosCallbackException.EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED} is returned.
+     * @return validation error code
+     */
+    @Override
+    public int validate() {
+        final InetSocketAddress sa = getAddressFromFileDescriptor();
+        if (sa == null) {
+            return QosCallbackException.EX_TYPE_FILTER_SOCKET_NOT_BOUND;
+        }
+
+        if (!sa.equals(mQosSocketInfo.getLocalSocketAddress())) {
+            return EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED;
+        }
+
+        return EX_TYPE_FILTER_NONE;
+    }
+
+    /**
+     * The local address of the socket's binding.
+     *
+     * Note: If the socket is no longer bound, null is returned.
+     *
+     * @return the local address
+     */
+    @Nullable
+    private InetSocketAddress getAddressFromFileDescriptor() {
+        final ParcelFileDescriptor parcelFileDescriptor = mQosSocketInfo.getParcelFileDescriptor();
+        if (parcelFileDescriptor == null) return null;
+
+        final FileDescriptor fd = parcelFileDescriptor.getFileDescriptor();
+        if (fd == null) return null;
+
+        final SocketAddress address;
+        try {
+            address = Os.getsockname(fd);
+        } catch (final ErrnoException e) {
+            Log.e(TAG, "getAddressFromFileDescriptor: getLocalAddress exception", e);
+            return null;
+        }
+        if (address instanceof InetSocketAddress) {
+            return (InetSocketAddress) address;
+        }
+        return null;
+    }
+
+    /**
+     * The network used with this filter.
+     *
+     * @return the registered {@link Network}
+     */
+    @NonNull
+    @Override
+    public Network getNetwork() {
+        return mQosSocketInfo.getNetwork();
+    }
+}
diff --git a/core/java/android/net/QosSocketInfo.aidl b/core/java/android/net/QosSocketInfo.aidl
new file mode 100644
index 0000000..476c090
--- /dev/null
+++ b/core/java/android/net/QosSocketInfo.aidl
@@ -0,0 +1,21 @@
+/*
+**
+** 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.net;
+
+parcelable QosSocketInfo;
+
diff --git a/core/java/android/net/QosSocketInfo.java b/core/java/android/net/QosSocketInfo.java
new file mode 100644
index 0000000..d37c469
--- /dev/null
+++ b/core/java/android/net/QosSocketInfo.java
@@ -0,0 +1,154 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/**
+ * Used in conjunction with
+ * {@link ConnectivityManager#registerQosCallback}
+ * in order to receive Qos Sessions related to the local address and port of a bound {@link Socket}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class QosSocketInfo implements Parcelable {
+
+    @NonNull
+    private final Network mNetwork;
+
+    @NonNull
+    private final ParcelFileDescriptor mParcelFileDescriptor;
+
+    @NonNull
+    private final InetSocketAddress mLocalSocketAddress;
+
+    /**
+     * The {@link Network} the socket is on.
+     *
+     * @return the registered {@link Network}
+     */
+    @NonNull
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
+    /**
+     * The parcel file descriptor wrapped around the socket's file descriptor.
+     *
+     * @return the parcel file descriptor of the socket
+     */
+    @NonNull
+    ParcelFileDescriptor getParcelFileDescriptor() {
+        return mParcelFileDescriptor;
+    }
+
+    /**
+     * The local address of the socket passed into {@link QosSocketInfo(Network, Socket)}.
+     * The value does not reflect any changes that occur to the socket after it is first set
+     * in the constructor.
+     *
+     * @return the local address of the socket
+     */
+    @NonNull
+    public InetSocketAddress getLocalSocketAddress() {
+        return mLocalSocketAddress;
+    }
+
+    /**
+     * Creates a {@link QosSocketInfo} given a {@link Network} and bound {@link Socket}.  The
+     * {@link Socket} must remain bound in order to receive {@link QosSession}s.
+     *
+     * @param network the network
+     * @param socket the bound {@link Socket}
+     */
+    public QosSocketInfo(@NonNull final Network network, @NonNull final Socket socket)
+            throws IOException {
+        Objects.requireNonNull(socket, "socket cannot be null");
+
+        mNetwork = Objects.requireNonNull(network, "network cannot be null");
+        mParcelFileDescriptor = ParcelFileDescriptor.dup(socket.getFileDescriptor$());
+        mLocalSocketAddress =
+                new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
+    }
+
+    /* Parcelable methods */
+    private QosSocketInfo(final Parcel in) {
+        mNetwork = Objects.requireNonNull(Network.CREATOR.createFromParcel(in));
+        mParcelFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
+
+        final int addressLength = in.readInt();
+        mLocalSocketAddress = readSocketAddress(in, addressLength);
+    }
+
+    private InetSocketAddress readSocketAddress(final Parcel in, final int addressLength) {
+        final byte[] address = new byte[addressLength];
+        in.readByteArray(address);
+        final int port = in.readInt();
+
+        try {
+            return new InetSocketAddress(InetAddress.getByAddress(address), port);
+        } catch (final UnknownHostException e) {
+            /* The catch block was purposely left empty.  UnknownHostException will never be thrown
+               since the address provided is numeric and non-null. */
+        }
+        return new InetSocketAddress();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull final Parcel dest, final int flags) {
+        mNetwork.writeToParcel(dest, 0);
+        mParcelFileDescriptor.writeToParcel(dest, 0);
+
+        final byte[] address = mLocalSocketAddress.getAddress().getAddress();
+        dest.writeInt(address.length);
+        dest.writeByteArray(address);
+        dest.writeInt(mLocalSocketAddress.getPort());
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<QosSocketInfo> CREATOR =
+            new Parcelable.Creator<QosSocketInfo>() {
+            @NonNull
+            @Override
+            public QosSocketInfo createFromParcel(final Parcel in) {
+                return new QosSocketInfo(in);
+            }
+
+            @NonNull
+            @Override
+            public QosSocketInfo[] newArray(final int size) {
+                return new QosSocketInfo[size];
+            }
+        };
+}
diff --git a/core/java/android/net/SocketLocalAddressChangedException.java b/core/java/android/net/SocketLocalAddressChangedException.java
new file mode 100644
index 0000000..9daad83
--- /dev/null
+++ b/core/java/android/net/SocketLocalAddressChangedException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.annotation.SystemApi;
+
+/**
+ * Thrown when the local address of the socket has changed.
+ *
+ * @hide
+ */
+@SystemApi
+public class SocketLocalAddressChangedException extends Exception {
+    /** @hide */
+    public SocketLocalAddressChangedException() {
+        super("The local address of the socket changed");
+    }
+}
diff --git a/core/java/android/net/SocketNotBoundException.java b/core/java/android/net/SocketNotBoundException.java
new file mode 100644
index 0000000..b1d7026
--- /dev/null
+++ b/core/java/android/net/SocketNotBoundException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.annotation.SystemApi;
+
+/**
+ * Thrown when a previously bound socket becomes unbound.
+ *
+ * @hide
+ */
+@SystemApi
+public class SocketNotBoundException extends Exception {
+    /** @hide */
+    public SocketNotBoundException() {
+        super("The socket is unbound");
+    }
+}
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index fdc3d65..71d2177 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -45,6 +45,8 @@
             POWER_COMPONENT_FLASHLIGHT,
             POWER_COMPONENT_MOBILE_RADIO,
             POWER_COMPONENT_SYSTEM_SERVICES,
+            POWER_COMPONENT_SENSORS,
+            POWER_COMPONENT_GNSS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public static @interface PowerComponent {
@@ -59,8 +61,10 @@
     public static final int POWER_COMPONENT_FLASHLIGHT = 6;
     public static final int POWER_COMPONENT_SYSTEM_SERVICES = 7;
     public static final int POWER_COMPONENT_MOBILE_RADIO = 8;
+    public static final int POWER_COMPONENT_SENSORS = 9;
+    public static final int POWER_COMPONENT_GNSS = 10;
 
-    public static final int POWER_COMPONENT_COUNT = 9;
+    public static final int POWER_COMPONENT_COUNT = 11;
 
     public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
     public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
@@ -90,6 +94,8 @@
             TIME_COMPONENT_CAMERA,
             TIME_COMPONENT_FLASHLIGHT,
             TIME_COMPONENT_MOBILE_RADIO,
+            TIME_COMPONENT_SENSORS,
+            TIME_COMPONENT_GNSS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public static @interface TimeComponent {
@@ -104,8 +110,10 @@
     public static final int TIME_COMPONENT_VIDEO = 6;
     public static final int TIME_COMPONENT_FLASHLIGHT = 7;
     public static final int TIME_COMPONENT_MOBILE_RADIO = 8;
+    public static final int TIME_COMPONENT_SENSORS = 9;
+    public static final int TIME_COMPONENT_GNSS = 10;
 
-    public static final int TIME_COMPONENT_COUNT = 9;
+    public static final int TIME_COMPONENT_COUNT = 11;
 
     public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000;
     public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 8148c45..e504946 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -318,6 +318,7 @@
          * @see #SDK_INT
          * @hide
          */
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         @TestApi
         public static final int FIRST_SDK_INT = SystemProperties
                 .getInt("ro.product.first_api_level", 0);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 6fe5777..b39c182 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -86,7 +86,7 @@
     Bundle getApplicationRestrictionsForUser(in String packageName, int userId);
     void setDefaultGuestRestrictions(in Bundle restrictions);
     Bundle getDefaultGuestRestrictions();
-    int removeUserOrSetEphemeral(int userId);
+    int removeUserOrSetEphemeral(int userId, boolean evenWhenDisallowed);
     boolean markGuestForDeletion(int userId);
     UserInfo findCurrentGuestUser();
     boolean isQuietModeEnabled(int userId);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index cbb3ba9..d11f3ce 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -416,21 +416,9 @@
     public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10;
 
     /**
-     * Go to sleep reason code: The last powered on display group has been removed.
      * @hide
      */
-    public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED = 11;
-
-    /**
-     * Go to sleep reason code: Every display group has been turned off.
-     * @hide
-     */
-    public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF = 12;
-
-    /**
-     * @hide
-     */
-    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF;
+    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_QUIESCENT;
 
     /**
      * @hide
@@ -447,8 +435,6 @@
             case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility";
             case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend";
             case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive";
-            case GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED: return "display_group_removed";
-            case GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF: return "display_groups_turned_off";
             default: return Integer.toString(sleepReason);
         }
     }
@@ -535,8 +521,6 @@
             WAKE_REASON_WAKE_KEY,
             WAKE_REASON_WAKE_MOTION,
             WAKE_REASON_HDMI,
-            WAKE_REASON_DISPLAY_GROUP_ADDED,
-            WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface WakeReason{}
@@ -624,18 +608,6 @@
     public static final int WAKE_REASON_LID = 9;
 
     /**
-     * Wake up reason code: Waking due to display group being added.
-     * @hide
-     */
-    public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10;
-
-    /**
-     * Wake up reason code: Waking due to display group being powered on.
-     * @hide
-     */
-    public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11;
-
-    /**
      * Convert the wake reason to a string for debugging purposes.
      * @hide
      */
@@ -651,8 +623,6 @@
             case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION";
             case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI";
             case WAKE_REASON_LID: return "WAKE_REASON_LID";
-            case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED";
-            case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON";
             default: return Integer.toString(wakeReason);
         }
     }
@@ -1244,15 +1214,8 @@
         }
     }
 
-    /**
-     * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
-     * to turn off.
-     *
-     * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
-     * turned on it will be turned off. If all displays are off as a result of this action the
-     * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT
-     * default display group} is already off then nothing will happen.
-     *
+   /**
+     * Forces the device to go to sleep.
      * <p>
      * Overrides all the wake locks that are held.
      * This is what happens when the power key is pressed to turn off the screen.
@@ -1275,14 +1238,7 @@
     }
 
     /**
-     * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
-     * to turn off.
-     *
-     * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
-     * turned on it will be turned off. If all displays are off as a result of this action the
-     * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT
-     * default display group} is already off then nothing will happen.
-     *
+     * Forces the device to go to sleep.
      * <p>
      * Overrides all the wake locks that are held.
      * This is what happens when the power key is pressed to turn off the screen.
@@ -1312,15 +1268,9 @@
     }
 
     /**
-     * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
-     * to turn on.
-     *
-     * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
-     * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
-     * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already
-     * on then nothing will happen.
-     *
+     * Forces the device to wake up from sleep.
      * <p>
+     * If the device is currently asleep, wakes it up, otherwise does nothing.
      * This is what happens when the power key is pressed to turn on the screen.
      * </p><p>
      * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
@@ -1343,15 +1293,9 @@
     }
 
     /**
-     * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
-     * to turn on.
-     *
-     * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
-     * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
-     * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already
-     * on then nothing will happen.
-     *
+     * Forces the device to wake up from sleep.
      * <p>
+     * If the device is currently asleep, wakes it up, otherwise does nothing.
      * This is what happens when the power key is pressed to turn on the screen.
      * </p><p>
      * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
@@ -1378,13 +1322,9 @@
     }
 
     /**
-     * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
-     *
-     * <p>If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will
-     * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link
-     * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen.
-     *
+     * Forces the device to wake up from sleep.
      * <p>
+     * If the device is currently asleep, wakes it up, otherwise does nothing.
      * This is what happens when the power key is pressed to turn on the screen.
      * </p><p>
      * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ed60baf..77183ac 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4058,14 +4058,18 @@
      * the current user, then set the user as ephemeral so that it will be removed when it is
      * stopped.
      *
+     * @param evenWhenDisallowed when {@code true}, user is removed even if the caller user has the
+     * {@link #DISALLOW_REMOVE_USER} or {@link #DISALLOW_REMOVE_MANAGED_PROFILE} restriction
+     *
      * @return the {@link RemoveResult} code
      * @hide
      */
     @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
             Manifest.permission.CREATE_USERS})
-    public @RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId) {
+    public @RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId,
+            boolean evenWhenDisallowed) {
         try {
-            return mService.removeUserOrSetEphemeral(userId);
+            return mService.removeUserOrSetEphemeral(userId, evenWhenDisallowed);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/os/storage/OWNERS b/core/java/android/os/storage/OWNERS
index 8af7de5..7e17a08 100644
--- a/core/java/android/os/storage/OWNERS
+++ b/core/java/android/os/storage/OWNERS
@@ -5,3 +5,6 @@
 corinac@google.com
 zezeozue@google.com
 maco@google.com
+sahanas@google.com
+abkaur@google.com
+chiangi@google.com
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 27ba72b..743713c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -89,8 +89,11 @@
 import com.android.internal.widget.ILockSettings;
 
 import java.io.IOException;
+import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -99,7 +102,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-
 /**
  * The Settings provider contains global system-level device preferences.
  */
@@ -2659,22 +2661,30 @@
         private final String mCallListCommand;
         private final String mCallSetAllCommand;
 
+        private final ArraySet<String> mReadableFields;
+        private final ArraySet<String> mAllFields;
+
         @GuardedBy("this")
         private GenerationTracker mGenerationTracker;
 
-        public NameValueCache(Uri uri, String getCommand, String setCommand,
-                ContentProviderHolder providerHolder) {
-            this(uri, getCommand, setCommand, null, null, providerHolder);
+        <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
+                String setCommand, ContentProviderHolder providerHolder, Class<T> callerClass) {
+            this(uri, getCommand, setCommand, null, null, providerHolder,
+                    callerClass);
         }
 
-        NameValueCache(Uri uri, String getCommand, String setCommand, String listCommand,
-                String setAllCommand, ContentProviderHolder providerHolder) {
+        private <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
+                String setCommand, String listCommand, String setAllCommand,
+                ContentProviderHolder providerHolder, Class<T> callerClass) {
             mUri = uri;
             mCallGetCommand = getCommand;
             mCallSetCommand = setCommand;
             mCallListCommand = listCommand;
             mCallSetAllCommand = setAllCommand;
             mProviderHolder = providerHolder;
+            mReadableFields = new ArraySet<>();
+            mAllFields = new ArraySet<>();
+            getPublicSettingsForClass(callerClass, mAllFields, mReadableFields);
         }
 
         public boolean putStringForUser(ContentResolver cr, String name, String value,
@@ -2726,6 +2736,18 @@
 
         @UnsupportedAppUsage
         public String getStringForUser(ContentResolver cr, String name, final int userHandle) {
+            // Check if the target settings key is readable. Reject if the caller is not system and
+            // is trying to access a settings key defined in the Settings.Secure, Settings.System or
+            // Settings.Global and is not annotated as @Readable.
+            // Notice that a key string that is not defined in any of the Settings.* classes will
+            // still be regarded as readable.
+            if (!Settings.isInSystemServer() && mAllFields.contains(name)
+                    && !mReadableFields.contains(name)) {
+                throw new SecurityException(
+                        "Settings key: <" + name + "> is not readable. From S+, new public "
+                        + "settings keys need to be annotated with @Readable unless they are "
+                        + "annotated with @hide.");
+            }
             final boolean isSelf = (userHandle == UserHandle.myUserId());
             int currentGeneration = -1;
             if (isSelf) {
@@ -3061,7 +3083,42 @@
      */
     public static boolean canDrawOverlays(Context context) {
         return Settings.isCallingPackageAllowedToDrawOverlays(context, Process.myUid(),
-                context.getOpPackageName(), false);
+                context.getOpPackageName(), false) || context.checkSelfPermission(
+                Manifest.permission.SYSTEM_APPLICATION_OVERLAY)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
+    /**
+     * This annotation indicates that the value of a setting is allowed to be read
+     * with the get* methods. The following settings should be readable:
+     * 1) all the public settings
+     * 2) all the hidden settings added before S
+     */
+    @Target({ ElementType.FIELD })
+    @Retention(RetentionPolicy.RUNTIME)
+    private @interface Readable {
+    }
+
+    private static <T extends NameValueTable> void getPublicSettingsForClass(
+            Class<T> callerClass, Set<String> allKeys, Set<String> readableKeys) {
+        final Field[] allFields = callerClass.getDeclaredFields();
+        try {
+            for (int i = 0; i < allFields.length; i++) {
+                final Field field = allFields[i];
+                if (!field.getType().equals(String.class)) {
+                    continue;
+                }
+                final Object value = field.get(callerClass);
+                if (!value.getClass().equals(String.class)) {
+                    continue;
+                }
+                allKeys.add((String) value);
+                if (field.getAnnotation(Readable.class) != null) {
+                    readableKeys.add((String) value);
+                }
+            }
+        } catch (IllegalAccessException ignored) {
+        }
     }
 
     /**
@@ -3091,7 +3148,8 @@
                 CONTENT_URI,
                 CALL_METHOD_GET_SYSTEM,
                 CALL_METHOD_PUT_SYSTEM,
-                sProviderHolder);
+                sProviderHolder,
+                System.class);
 
         @UnsupportedAppUsage
         private static final HashSet<String> MOVED_TO_SECURE;
@@ -3145,8 +3203,11 @@
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.BLUETOOTH_ON);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DATA_ROAMING);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DEVICE_PROVISIONED);
-            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.HTTP_PROXY);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.NETWORK_PREFERENCE);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MAX_DHCP_RETRY_COUNT);
 
             // these are moving directly from system to global
             MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_ON);
@@ -3184,6 +3245,12 @@
             MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_NFC);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_CELL);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIFI);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_BLUETOOTH);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIMAX);
+            MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
         }
 
         /** @hide */
@@ -3208,6 +3275,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(System.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -3232,6 +3304,7 @@
                         + " to android.provider.Settings.Global, returning read-only value.");
                 return Global.getStringForUser(resolver, name, userHandle);
             }
+
             return sNameValueCache.getStringForUser(resolver, name, userHandle);
         }
 
@@ -3709,6 +3782,7 @@
          * 3 - The end button goes to the home screen.  If the user is already on the
          * home screen, it puts the device to sleep.
          */
+        @Readable
         public static final String END_BUTTON_BEHAVIOR = "end_button_behavior";
 
         /**
@@ -3733,6 +3807,7 @@
          * Is advanced settings mode turned on. 0 == no, 1 == yes
          * @hide
          */
+        @Readable
         public static final String ADVANCED_SETTINGS = "advanced_settings";
 
         /**
@@ -3833,6 +3908,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_USE_STATIC_IP = "wifi_use_static_ip";
 
         /**
@@ -3843,6 +3919,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_IP = "wifi_static_ip";
 
         /**
@@ -3853,6 +3930,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_GATEWAY = "wifi_static_gateway";
 
         /**
@@ -3863,6 +3941,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_NETMASK = "wifi_static_netmask";
 
         /**
@@ -3873,6 +3952,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_DNS1 = "wifi_static_dns1";
 
         /**
@@ -3883,6 +3963,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_DNS2 = "wifi_static_dns2";
 
         /**
@@ -3893,6 +3974,7 @@
          * 1 -- connectable but not discoverable
          * 0 -- neither connectable nor discoverable
          */
+        @Readable
         public static final String BLUETOOTH_DISCOVERABILITY =
             "bluetooth_discoverability";
 
@@ -3901,6 +3983,7 @@
          * Bluetooth becomes discoverable for a certain number of seconds,
          * after which is becomes simply connectable.  The value is in seconds.
          */
+        @Readable
         public static final String BLUETOOTH_DISCOVERABILITY_TIMEOUT =
             "bluetooth_discoverability_timeout";
 
@@ -3934,11 +4017,13 @@
          * @deprecated Use {@link android.app.AlarmManager#getNextAlarmClock()}.
          */
         @Deprecated
+        @Readable
         public static final String NEXT_ALARM_FORMATTED = "next_alarm_formatted";
 
         /**
          * Scaling factor for fonts, float.
          */
+        @Readable
         public static final String FONT_SCALE = "font_scale";
 
         /**
@@ -3950,6 +4035,7 @@
          * instead.
          * @hide
          */
+        @Readable
         public static final String SYSTEM_LOCALES = "system_locales";
 
 
@@ -3975,12 +4061,14 @@
          * @deprecated This setting is no longer used.
          */
         @Deprecated
+        @Readable
         public static final String DIM_SCREEN = "dim_screen";
 
         /**
          * The display color mode.
          * @hide
          */
+        @Readable
         public static final String DISPLAY_COLOR_MODE = "display_color_mode";
 
         /**
@@ -3989,6 +4077,7 @@
          * If this isn't set, 0 will be used.
          * @hide
          */
+        @Readable
         public static final String MIN_REFRESH_RATE = "min_refresh_rate";
 
         /**
@@ -3997,6 +4086,7 @@
          * If this isn't set, the system falls back to a device specific default.
          * @hide
          */
+        @Readable
         public static final String PEAK_REFRESH_RATE = "peak_refresh_rate";
 
         /**
@@ -4009,23 +4099,27 @@
          * This value is bounded by maximum timeout set by
          * {@link android.app.admin.DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)}.
          */
+        @Readable
         public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
 
         /**
          * The screen backlight brightness between 0 and 255.
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS = "screen_brightness";
 
         /**
          * The screen backlight brightness between 0 and 255.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FOR_VR = "screen_brightness_for_vr";
 
         /**
          * The screen backlight brightness between 0.0f and 1.0f.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FOR_VR_FLOAT =
                 "screen_brightness_for_vr_float";
 
@@ -4033,11 +4127,13 @@
          * The screen backlight brightness between 0.0f and 1.0f.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FLOAT = "screen_brightness_float";
 
         /**
          * Control whether to enable automatic brightness mode.
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";
 
         /**
@@ -4046,6 +4142,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String SCREEN_AUTO_BRIGHTNESS_ADJ = "screen_auto_brightness_adj";
 
         /**
@@ -4089,6 +4186,7 @@
          * stream type's bit should be set to 1 if it should be muted when going
          * into an inaudible ringer mode.
          */
+        @Readable
         public static final String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
 
         /**
@@ -4096,12 +4194,14 @@
           * stream type's bit should be set to 1 if it should be muted when a mute request
           * is received.
           */
+        @Readable
         public static final String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
 
         /**
          * Whether vibrate is on for different events. This is used internally,
          * changing this value will not change the vibrate. See AudioManager.
          */
+        @Readable
         public static final String VIBRATE_ON = "vibrate_on";
 
         /**
@@ -4116,6 +4216,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VIBRATE_INPUT_DEVICES = "vibrate_input_devices";
 
         /**
@@ -4132,6 +4233,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_VIBRATION_INTENSITY =
                 "notification_vibration_intensity";
         /**
@@ -4148,6 +4250,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String RING_VIBRATION_INTENSITY =
                 "ring_vibration_intensity";
 
@@ -4165,6 +4268,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String HAPTIC_FEEDBACK_INTENSITY =
                 "haptic_feedback_intensity";
 
@@ -4174,6 +4278,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_RING = "volume_ring";
 
         /**
@@ -4182,6 +4287,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_SYSTEM = "volume_system";
 
         /**
@@ -4190,6 +4296,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_VOICE = "volume_voice";
 
         /**
@@ -4198,6 +4305,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_MUSIC = "volume_music";
 
         /**
@@ -4206,6 +4314,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_ALARM = "volume_alarm";
 
         /**
@@ -4214,6 +4323,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_NOTIFICATION = "volume_notification";
 
         /**
@@ -4222,6 +4332,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
 
         /**
@@ -4229,12 +4340,14 @@
          * Acessibility volume. This is used internally, changing this
          * value will not change the volume.
          */
+        @Readable
         public static final String VOLUME_ACCESSIBILITY = "volume_a11y";
 
         /**
          * @hide
          * Volume index for virtual assistant.
          */
+        @Readable
         public static final String VOLUME_ASSISTANT = "volume_assistant";
 
         /**
@@ -4242,6 +4355,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VOLUME_MASTER = "volume_master";
 
         /**
@@ -4250,6 +4364,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String MASTER_MONO = "master_mono";
 
         /**
@@ -4257,6 +4372,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MASTER_BALANCE = "master_balance";
 
         /**
@@ -4274,6 +4390,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String NOTIFICATIONS_USE_RING_VOLUME =
             "notifications_use_ring_volume";
 
@@ -4290,6 +4407,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";
 
         /**
@@ -4325,6 +4443,7 @@
          *
          * @removed  Not used by anything since API 2.
          */
+        @Readable
         public static final String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
 
         /**
@@ -4336,6 +4455,7 @@
          *
          * @see #DEFAULT_RINGTONE_URI
          */
+        @Readable
         public static final String RINGTONE = "ringtone";
 
         /**
@@ -4359,6 +4479,7 @@
          * @see #RINGTONE
          * @see #DEFAULT_NOTIFICATION_URI
          */
+        @Readable
         public static final String NOTIFICATION_SOUND = "notification_sound";
 
         /**
@@ -4380,6 +4501,7 @@
          * @see #RINGTONE
          * @see #DEFAULT_ALARM_ALERT_URI
          */
+        @Readable
         public static final String ALARM_ALERT = "alarm_alert";
 
         /**
@@ -4400,29 +4522,35 @@
          *
          * @hide
          */
+        @Readable
         public static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver";
 
         /**
          * Setting to enable Auto Replace (AutoText) in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_AUTO_REPLACE = "auto_replace";
 
         /**
          * Setting to enable Auto Caps in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_AUTO_CAPS = "auto_caps";
 
         /**
          * Setting to enable Auto Punctuate in text editors. 1 = On, 0 = Off. This
          * feature converts two spaces to a "." and space.
          */
+        @Readable
         public static final String TEXT_AUTO_PUNCTUATE = "auto_punctuate";
 
         /**
          * Setting to showing password characters in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_SHOW_PASSWORD = "show_password";
 
+        @Readable
         public static final String SHOW_GTALK_SERVICE_STATUS =
                 "SHOW_GTALK_SERVICE_STATUS";
 
@@ -4432,6 +4560,7 @@
          * @deprecated Use {@link WallpaperManager} instead.
          */
         @Deprecated
+        @Readable
         public static final String WALLPAPER_ACTIVITY = "wallpaper_activity";
 
         /**
@@ -4453,6 +4582,7 @@
          *   12
          *   24
          */
+        @Readable
         public static final String TIME_12_24 = "time_12_24";
 
         /**
@@ -4461,6 +4591,7 @@
          *   dd/mm/yyyy
          *   yyyy/mm/dd
          */
+        @Readable
         public static final String DATE_FORMAT = "date_format";
 
         /**
@@ -4470,6 +4601,7 @@
          * nonzero = it has been run in the past
          * 0 = it has not been run in the past
          */
+        @Readable
         public static final String SETUP_WIZARD_HAS_RUN = "setup_wizard_has_run";
 
         /**
@@ -4506,6 +4638,7 @@
          * by the application; if 1, it will be used by default unless explicitly
          * disabled by the application.
          */
+        @Readable
         public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
 
         /**
@@ -4516,6 +4649,7 @@
          *
          * @see Display#getRotation
          */
+        @Readable
         public static final String USER_ROTATION = "user_rotation";
 
         /**
@@ -4530,6 +4664,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY =
                 "hide_rotation_lock_toggle_for_accessibility";
 
@@ -4543,6 +4678,7 @@
          * relied on the setting, while this is purely about the vibration setting for incoming
          * calls.
          */
+        @Readable
         public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
 
         /**
@@ -4550,6 +4686,7 @@
          * {@code 0}, enhanced call blocking functionality is disabled.
          * @hide
          */
+        @Readable
         public static final String DEBUG_ENABLE_ENHANCED_CALL_BLOCKING =
                 "debug.enable_enhanced_calling";
 
@@ -4557,6 +4694,7 @@
          * Whether the audible DTMF tones are played by the dialer when dialing. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
 
         /**
@@ -4565,6 +4703,7 @@
          *                 0 = Normal
          *                 1 = Long
          */
+        @Readable
         public static final String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type";
 
         /**
@@ -4573,6 +4712,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String HEARING_AID = "hearing_aid";
 
         /**
@@ -4585,18 +4725,21 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String TTY_MODE = "tty_mode";
 
         /**
          * Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
 
         /**
          * Whether haptic feedback (Vibrate on tap) is enabled. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String HAPTIC_FEEDBACK_ENABLED = "haptic_feedback_enabled";
 
         /**
@@ -4604,6 +4747,7 @@
          * setting for this.
          */
         @Deprecated
+        @Readable
         public static final String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
 
         /**
@@ -4612,6 +4756,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
 
         /**
@@ -4621,6 +4766,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String POINTER_LOCATION = "pointer_location";
 
         /**
@@ -4630,6 +4776,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String SHOW_TOUCHES = "show_touches";
 
         /**
@@ -4640,6 +4787,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String WINDOW_ORIENTATION_LISTENER_LOG =
                 "window_orientation_listener_log";
 
@@ -4665,12 +4813,14 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled";
 
         /**
          * Whether the lockscreen should be completely disabled.
          * @hide
          */
+        @Readable
         public static final String LOCKSCREEN_DISABLED = "lockscreen.disabled";
 
         /**
@@ -4741,6 +4891,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String SIP_RECEIVE_CALLS = "sip_receive_calls";
 
         /**
@@ -4749,18 +4900,21 @@
          * "SIP_ADDRESS_ONLY" : Only if destination is a SIP address
          * @hide
          */
+        @Readable
         public static final String SIP_CALL_OPTIONS = "sip_call_options";
 
         /**
          * One of the sip call options: Always use SIP with network access.
          * @hide
          */
+        @Readable
         public static final String SIP_ALWAYS = "SIP_ALWAYS";
 
         /**
          * One of the sip call options: Only if destination is a SIP address.
          * @hide
          */
+        @Readable
         public static final String SIP_ADDRESS_ONLY = "SIP_ADDRESS_ONLY";
 
         /**
@@ -4771,6 +4925,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
 
         /**
@@ -4782,12 +4937,14 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String POINTER_SPEED = "pointer_speed";
 
         /**
          * Whether lock-to-app will be triggered by long-press on recents.
          * @hide
          */
+        @Readable
         public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
 
         /**
@@ -4797,6 +4954,7 @@
          * Backward-compatible with <code>PrefGetPreference(prefAllowEasterEggs)</code>.
          * @hide
          */
+        @Readable
         public static final String EGG_MODE = "egg_mode";
 
         /**
@@ -4805,6 +4963,7 @@
          *    1 - Show percentage
          * @hide
          */
+        @Readable
         public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
 
         /**
@@ -4813,6 +4972,7 @@
          * for instance pausing media apps when another starts.
          * @hide
          */
+        @Readable
         public static final String MULTI_AUDIO_FOCUS_ENABLED = "multi_audio_focus_enabled";
 
         /**
@@ -5006,6 +5166,7 @@
          * @see android.telephony.TelephonyManager.WifiCallingChoices
          * @hide
          */
+        @Readable
         public static final String WHEN_TO_MAKE_WIFI_CALLS = "when_to_make_wifi_calls";
 
         // Settings moved to Settings.Secure
@@ -5162,6 +5323,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE =
                 Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE;
 
@@ -5176,6 +5338,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS;
 
@@ -5184,6 +5347,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED;
 
@@ -5193,6 +5357,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS;
 
@@ -5201,6 +5366,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT =
             Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT;
 
@@ -5235,6 +5401,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS =
             Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS;
 
@@ -5284,7 +5451,8 @@
                 CONTENT_URI,
                 CALL_METHOD_GET_SECURE,
                 CALL_METHOD_PUT_SECURE,
-                sProviderHolder);
+                sProviderHolder,
+                Secure.class);
 
         private static ILockSettings sLockSettings = null;
 
@@ -5422,6 +5590,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(Secure.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -5917,6 +6090,7 @@
          * Control whether to enable adaptive sleep mode.
          * @hide
          */
+        @Readable
         public static final String ADAPTIVE_SLEEP = "adaptive_sleep";
 
         /**
@@ -5934,6 +6108,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
 
         /**
@@ -5951,6 +6126,7 @@
          * @deprecated This settings is not used anymore.
          */
         @Deprecated
+        @Readable
         public static final String ALLOW_MOCK_LOCATION = "mock_location";
 
         /**
@@ -5959,6 +6135,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled";
 
         /**
@@ -5998,6 +6175,7 @@
          * to the Instant App, it is generated when the Instant App is first installed and reset if
          * the user clears the Instant App.
          */
+        @Readable
         public static final String ANDROID_ID = "android_id";
 
         /**
@@ -6016,12 +6194,14 @@
          * Setting to record the input method used by default, holding the ID
          * of the desired method.
          */
+        @Readable
         public static final String DEFAULT_INPUT_METHOD = "default_input_method";
 
         /**
          * Setting to record the input method subtype used by default, holding the ID
          * of the desired method.
          */
+        @Readable
         public static final String SELECTED_INPUT_METHOD_SUBTYPE =
                 "selected_input_method_subtype";
 
@@ -6030,12 +6210,14 @@
          * and its last used subtype.
          * @hide
          */
+        @Readable
         public static final String INPUT_METHODS_SUBTYPE_HISTORY =
                 "input_methods_subtype_history";
 
         /**
          * Setting to record the visibility of input method selector
          */
+        @Readable
         public static final String INPUT_METHOD_SELECTOR_VISIBILITY =
                 "input_method_selector_visibility";
 
@@ -6044,6 +6226,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
 
         /**
@@ -6051,6 +6234,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String AUTOFILL_SERVICE = "autofill_service";
 
         /**
@@ -6061,6 +6245,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION =
                 "autofill_field_classification";
 
@@ -6069,6 +6254,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DARK_MODE_DIALOG_SEEN =
                 "dark_mode_dialog_seen";
 
@@ -6077,6 +6263,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String DARK_THEME_CUSTOM_START_TIME =
                 "dark_theme_custom_start_time";
 
@@ -6085,6 +6272,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String DARK_THEME_CUSTOM_END_TIME =
                 "dark_theme_custom_end_time";
 
@@ -6094,6 +6282,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE =
                 "autofill_user_data_max_user_data_size";
 
@@ -6104,6 +6293,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE =
                 "autofill_user_data_max_field_classification_size";
 
@@ -6114,6 +6304,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT =
                 "autofill_user_data_max_category_count";
 
@@ -6123,6 +6314,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH =
                 "autofill_user_data_max_value_length";
 
@@ -6132,6 +6324,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH =
                 "autofill_user_data_min_value_length";
 
@@ -6144,6 +6337,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
 
         /**
@@ -6161,6 +6355,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MANAGED_PROVISIONING_DPC_DOWNLOADED =
                 "managed_provisioning_dpc_downloaded";
 
@@ -6171,6 +6366,7 @@
          * <p>
          * Type: int (0 for false, 1 for true)
          */
+        @Readable
         public static final String SECURE_FRP_MODE = "secure_frp_mode";
 
         /**
@@ -6181,6 +6377,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String USER_SETUP_COMPLETE = "user_setup_complete";
 
         /**
@@ -6236,6 +6433,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String USER_SETUP_PERSONALIZATION_STATE =
                 "user_setup_personalization_state";
 
@@ -6246,6 +6444,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TV_USER_SETUP_COMPLETE = "tv_user_setup_complete";
 
         /**
@@ -6257,6 +6456,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
 
         /**
@@ -6267,6 +6467,7 @@
          * Format like "ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0"
          * where imeId is ComponentName and subtype is int32.
          */
+        @Readable
         public static final String ENABLED_INPUT_METHODS = "enabled_input_methods";
 
         /**
@@ -6275,6 +6476,7 @@
          * by ':'.
          * @hide
          */
+        @Readable
         public static final String DISABLED_SYSTEM_INPUT_METHODS = "disabled_system_input_methods";
 
         /**
@@ -6283,6 +6485,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard";
 
@@ -6300,6 +6503,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_APP = "always_on_vpn_app";
 
         /**
@@ -6308,6 +6512,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_LOCKDOWN = "always_on_vpn_lockdown";
 
         /**
@@ -6317,6 +6522,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_LOCKDOWN_WHITELIST =
                 "always_on_vpn_lockdown_whitelist";
 
@@ -6330,6 +6536,8 @@
          * {@link PackageManager#canRequestPackageInstalls()}
          * @see PackageManager#canRequestPackageInstalls()
          */
+        @Deprecated
+        @Readable
         public static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
 
         /**
@@ -6341,6 +6549,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String UNKNOWN_SOURCES_DEFAULT_REVERSED =
                 "unknown_sources_default_reversed";
 
@@ -6354,6 +6563,7 @@
          * instead.
          */
         @Deprecated
+        @Readable
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
@@ -6365,12 +6575,14 @@
          * {@link LocationManager#MODE_CHANGED_ACTION}.
          */
         @Deprecated
+        @Readable
         public static final String LOCATION_MODE = "location_mode";
 
         /**
          * The App or module that changes the location mode.
          * @hide
          */
+        @Readable
         public static final String LOCATION_CHANGER = "location_changer";
 
         /**
@@ -6439,6 +6651,7 @@
          * android.app.timezonedetector.TimeZoneDetector#updateConfiguration} to update.
          * @hide
          */
+        @Readable
         public static final String LOCATION_TIME_ZONE_DETECTION_ENABLED =
                 "location_time_zone_detection_enabled";
 
@@ -6448,6 +6661,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_COARSE_ACCURACY_M = "locationCoarseAccuracy";
 
         /**
@@ -6455,6 +6669,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_BIOMETRIC_WEAK_FLAGS =
                 "lock_biometric_weak_flags";
 
@@ -6462,6 +6677,7 @@
          * Whether lock-to-app will lock the keyguard when exiting.
          * @hide
          */
+        @Readable
         public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked";
 
         /**
@@ -6472,6 +6688,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
 
         /**
@@ -6481,6 +6698,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
 
         /**
@@ -6494,6 +6712,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String
                 LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
 
@@ -6503,6 +6722,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout";
 
 
@@ -6512,6 +6732,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info";
 
         /**
@@ -6519,6 +6740,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_APPWIDGET_IDS =
             "lock_screen_appwidget_ids";
 
@@ -6527,6 +6749,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID =
             "lock_screen_fallback_appwidget_id";
 
@@ -6535,6 +6758,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_STICKY_APPWIDGET =
             "lock_screen_sticky_appwidget";
 
@@ -6545,6 +6769,7 @@
          */
         @Deprecated
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
             "lock_screen_owner_info_enabled";
 
@@ -6557,6 +6782,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
                 "lock_screen_allow_private_notifications";
 
@@ -6565,6 +6791,7 @@
          * without having to unlock
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_ALLOW_REMOTE_INPUT =
                 "lock_screen_allow_remote_input";
 
@@ -6574,12 +6801,14 @@
          *     {"clock": id, "_applied_timestamp": timestamp}
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_CUSTOM_CLOCK_FACE = "lock_screen_custom_clock_face";
 
         /**
          * Indicates which clock face to show on lock screen and AOD while docked.
          * @hide
          */
+        @Readable
         public static final String DOCKED_CLOCK_FACE = "docked_clock_face";
 
         /**
@@ -6587,6 +6816,7 @@
          * the lockscreen notification policy.
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTE_ABOUT_NOTIFICATION_HIDING =
                 "show_note_about_notification_hiding";
 
@@ -6594,6 +6824,7 @@
          * Set to 1 by the system after trust agents have been initialized.
          * @hide
          */
+        @Readable
         public static final String TRUST_AGENTS_INITIALIZED =
                 "trust_agents_initialized";
 
@@ -6604,6 +6835,7 @@
          * many collisions.  It should not be used.
          */
         @Deprecated
+        @Readable
         public static final String LOGGING_ID = "logging_id";
 
         /**
@@ -6615,16 +6847,19 @@
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
 
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
 
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
 
         /**
@@ -6633,6 +6868,7 @@
          * and new Settings apps.
          */
         // TODO: 881807
+        @Readable
         public static final String SETTINGS_CLASSNAME = "settings_classname";
 
         /**
@@ -6650,12 +6886,14 @@
         /**
          * If accessibility is enabled.
          */
+        @Readable
         public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
 
         /**
          * Setting specifying if the accessibility shortcut is enabled.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN =
                 "accessibility_shortcut_on_lock_screen";
 
@@ -6663,6 +6901,7 @@
          * Setting specifying if the accessibility shortcut dialog has been shown to this user.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN =
                 "accessibility_shortcut_dialog_shown";
 
@@ -6677,6 +6916,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE =
                 "accessibility_shortcut_target_service";
 
@@ -6687,6 +6927,7 @@
          * accessibility feature.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_TARGET_COMPONENT =
                 "accessibility_button_target_component";
 
@@ -6699,6 +6940,7 @@
          * accessibility feature.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_TARGETS = "accessibility_button_targets";
 
         /**
@@ -6707,17 +6949,20 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER =
                 "com.android.server.accessibility.MagnificationController";
 
         /**
          * If touch exploration is enabled.
          */
+        @Readable
         public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
 
         /**
          * List of the enabled accessibility providers.
          */
+        @Readable
         public static final String ENABLED_ACCESSIBILITY_SERVICES =
             "enabled_accessibility_services";
 
@@ -6727,6 +6972,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
             "touch_exploration_granted_accessibility_services";
 
@@ -6734,12 +6980,14 @@
          * Whether the Global Actions Panel is enabled.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_ENABLED = "global_actions_panel_enabled";
 
         /**
          * Whether the Global Actions Panel can be toggled on or off in Settings.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_AVAILABLE =
                 "global_actions_panel_available";
 
@@ -6747,6 +6995,7 @@
          * Enables debug mode for the Global Actions Panel.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_DEBUG_ENABLED =
                 "global_actions_panel_debug_enabled";
 
@@ -6755,24 +7004,28 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String HUSH_GESTURE_USED = "hush_gesture_used";
 
         /**
          * Number of times the user has manually clicked the ringer toggle
          * @hide
          */
+        @Readable
         public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
 
         /**
          * Whether to play a sound for charging events.
          * @hide
          */
+        @Readable
         public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
 
         /**
          * Whether to vibrate for charging events.
          * @hide
          */
+        @Readable
         public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
 
         /**
@@ -6782,6 +7035,7 @@
          * user to specify a duration.
          * @hide
          */
+        @Readable
         public static final String ZEN_DURATION = "zen_duration";
 
         /** @hide */ public static final int ZEN_DURATION_PROMPT = -1;
@@ -6791,24 +7045,28 @@
          * If nonzero, will show the zen upgrade notification when the user toggles DND on/off.
          * @hide
          */
+        @Readable
         public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification";
 
         /**
          * If nonzero, will show the zen update settings suggestion.
          * @hide
          */
+        @Readable
         public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion";
 
         /**
          * If nonzero, zen has not been updated to reflect new changes.
          * @hide
          */
+        @Readable
         public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated";
 
         /**
          * If nonzero, zen setting suggestion has been viewed by user
          * @hide
          */
+        @Readable
         public static final String ZEN_SETTINGS_SUGGESTION_VIEWED =
                 "zen_settings_suggestion_viewed";
 
@@ -6817,6 +7075,7 @@
          * boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String IN_CALL_NOTIFICATION_ENABLED = "in_call_notification_enabled";
 
         /**
@@ -6825,6 +7084,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri";
 
         /**
@@ -6837,6 +7097,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FONT_WEIGHT_ADJUSTMENT = "font_weight_adjustment";
 
         /**
@@ -6847,6 +7108,7 @@
          * at all times, which was the behavior when this value was {@code true}.
          */
         @Deprecated
+        @Readable
         public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
 
         /**
@@ -6854,6 +7116,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED =
                 "high_text_contrast_enabled";
 
@@ -6867,6 +7130,7 @@
          */
         @UnsupportedAppUsage
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED =
                 "accessibility_display_magnification_enabled";
 
@@ -6882,6 +7146,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED =
                 "accessibility_display_magnification_navbar_enabled";
 
@@ -6895,6 +7160,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE =
                 "accessibility_display_magnification_scale";
 
@@ -6905,6 +7171,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE =
                 "accessibility_display_magnification_auto_update";
 
@@ -6914,6 +7181,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SOFT_KEYBOARD_MODE =
                 "accessibility_soft_keyboard_mode";
 
@@ -6947,6 +7215,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_ENABLED =
                 "accessibility_captioning_enabled";
 
@@ -6957,6 +7226,7 @@
          * @see java.util.Locale#toString
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_LOCALE =
                 "accessibility_captioning_locale";
 
@@ -6971,6 +7241,7 @@
          * @see java.util.Locale#toString
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_PRESET =
                 "accessibility_captioning_preset";
 
@@ -6981,6 +7252,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR =
                 "accessibility_captioning_background_color";
 
@@ -6991,6 +7263,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR =
                 "accessibility_captioning_foreground_color";
 
@@ -7005,6 +7278,7 @@
          * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE =
                 "accessibility_captioning_edge_type";
 
@@ -7016,6 +7290,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR =
                 "accessibility_captioning_edge_color";
 
@@ -7026,6 +7301,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR =
                 "accessibility_captioning_window_color";
 
@@ -7042,6 +7318,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE =
                 "accessibility_captioning_typeface";
 
@@ -7050,12 +7327,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE =
                 "accessibility_captioning_font_scale";
 
         /**
          * Setting that specifies whether display color inversion is enabled.
          */
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
                 "accessibility_display_inversion_enabled";
 
@@ -7066,6 +7345,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED =
                 "accessibility_display_daltonizer_enabled";
 
@@ -7082,6 +7362,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_DALTONIZER =
                 "accessibility_display_daltonizer";
 
@@ -7092,6 +7373,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_AUTOCLICK_ENABLED =
                 "accessibility_autoclick_enabled";
 
@@ -7102,6 +7384,7 @@
          * @see #ACCESSIBILITY_AUTOCLICK_ENABLED
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_AUTOCLICK_DELAY =
                 "accessibility_autoclick_delay";
 
@@ -7112,6 +7395,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_LARGE_POINTER_ICON =
                 "accessibility_large_pointer_icon";
 
@@ -7120,6 +7404,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
 
         /**
@@ -7127,6 +7412,7 @@
          * down event for an interaction to be considered part of the same multi-press.
          * @hide
          */
+        @Readable
         public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout";
 
         /**
@@ -7135,6 +7421,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS =
                 "accessibility_non_interactive_ui_timeout_ms";
 
@@ -7144,6 +7431,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS =
                 "accessibility_interactive_ui_timeout_ms";
 
@@ -7154,6 +7442,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_ACTIVATED =
                 "reduce_bright_colors_activated";
 
@@ -7163,6 +7452,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_LEVEL =
                 "reduce_bright_colors_level";
 
@@ -7171,6 +7461,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS =
                 "reduce_bright_colors_persist_across_reboots";
 
@@ -7183,6 +7474,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLED_PRINT_SERVICES =
             "enabled_print_services";
 
@@ -7192,6 +7484,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DISABLED_PRINT_SERVICES =
             "disabled_print_services";
 
@@ -7202,6 +7495,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DISPLAY_DENSITY_FORCED = "display_density_forced";
 
         /**
@@ -7214,21 +7508,25 @@
          * the framework text to speech APIs as of the Ice Cream Sandwich release.
          */
         @Deprecated
+        @Readable
         public static final String TTS_USE_DEFAULTS = "tts_use_defaults";
 
         /**
          * Default text-to-speech engine speech rate. 100 = 1x
          */
+        @Readable
         public static final String TTS_DEFAULT_RATE = "tts_default_rate";
 
         /**
          * Default text-to-speech engine pitch. 100 = 1x
          */
+        @Readable
         public static final String TTS_DEFAULT_PITCH = "tts_default_pitch";
 
         /**
          * Default text-to-speech engine.
          */
+        @Readable
         public static final String TTS_DEFAULT_SYNTH = "tts_default_synth";
 
         /**
@@ -7240,6 +7538,7 @@
          * locale. {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_LANG = "tts_default_lang";
 
         /**
@@ -7251,6 +7550,7 @@
          * locale. {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_COUNTRY = "tts_default_country";
 
         /**
@@ -7262,6 +7562,7 @@
          * locale that is in use {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_VARIANT = "tts_default_variant";
 
         /**
@@ -7276,11 +7577,13 @@
          *
          * @hide
          */
+        @Readable
         public static final String TTS_DEFAULT_LOCALE = "tts_default_locale";
 
         /**
          * Space delimited list of plugin packages that are enabled.
          */
+        @Readable
         public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins";
 
         /**
@@ -7320,6 +7623,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE =
                 "wifi_watchdog_acceptable_packet_loss_percentage";
 
@@ -7329,6 +7633,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count";
 
         /**
@@ -7336,6 +7641,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS =
                 "wifi_watchdog_background_check_delay_ms";
 
@@ -7345,6 +7651,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED =
                 "wifi_watchdog_background_check_enabled";
 
@@ -7353,6 +7660,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS =
                 "wifi_watchdog_background_check_timeout_ms";
 
@@ -7364,6 +7672,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT =
             "wifi_watchdog_initial_ignored_ping_count";
 
@@ -7375,12 +7684,14 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks";
 
         /**
          * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
 
         /**
@@ -7388,6 +7699,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
 
         /**
@@ -7395,6 +7707,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
 
         /**
@@ -7402,6 +7715,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
 
         /**
@@ -7409,6 +7723,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
 
         /**
@@ -7433,6 +7748,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS =
                 "connectivity_release_pending_intent_delay_ms";
 
@@ -7446,12 +7762,14 @@
          *             now appear disconnected.
          */
         @Deprecated
+        @Readable
         public static final String BACKGROUND_DATA = "background_data";
 
         /**
          * Origins for which browsers should allow geolocation by default.
          * The value is a space-separated list of origins.
          */
+        @Readable
         public static final String ALLOWED_GEOLOCATION_ORIGINS
                 = "allowed_geolocation_origins";
 
@@ -7462,6 +7780,7 @@
          *                            3 = TTY VCO
          * @hide
          */
+        @Readable
         public static final String PREFERRED_TTY_MODE =
                 "preferred_tty_mode";
 
@@ -7471,6 +7790,7 @@
          * 1 = enhanced voice privacy
          * @hide
          */
+        @Readable
         public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled";
 
         /**
@@ -7479,6 +7799,7 @@
          * 1 = enabled
          * @hide
          */
+        @Readable
         public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
 
         /**
@@ -7487,6 +7808,7 @@
          * 0 = OFF
          * 1 = ON
          */
+        @Readable
         public static final String RTT_CALLING_MODE = "rtt_calling_mode";
 
         /**
@@ -7496,6 +7818,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_ENABLED = "backup_enabled";
 
         /**
@@ -7505,6 +7828,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore";
 
         /**
@@ -7513,6 +7837,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_PROVISIONED = "backup_provisioned";
 
         /**
@@ -7520,6 +7845,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_TRANSPORT = "backup_transport";
 
         /**
@@ -7529,6 +7855,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LAST_SETUP_SHOWN = "last_setup_shown";
 
         /**
@@ -7551,6 +7878,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY =
                 "search_global_search_activity";
 
@@ -7558,21 +7886,25 @@
          * The number of promoted sources in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_NUM_PROMOTED_SOURCES = "search_num_promoted_sources";
         /**
          * The maximum number of suggestions returned by GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_RESULTS_TO_DISPLAY = "search_max_results_to_display";
         /**
          * The number of suggestions GlobalSearch will ask each non-web search source for.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_RESULTS_PER_SOURCE = "search_max_results_per_source";
         /**
          * The number of suggestions the GlobalSearch will ask the web search source for.
          * @hide
          */
+        @Readable
         public static final String SEARCH_WEB_RESULTS_OVERRIDE_LIMIT =
                 "search_web_results_override_limit";
         /**
@@ -7580,69 +7912,81 @@
          * promoted sources before continuing with all other sources.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS =
                 "search_promoted_source_deadline_millis";
         /**
          * The number of milliseconds before GlobalSearch aborts search suggesiton queries.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SOURCE_TIMEOUT_MILLIS = "search_source_timeout_millis";
         /**
          * The maximum number of milliseconds that GlobalSearch shows the previous results
          * after receiving a new query.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PREFILL_MILLIS = "search_prefill_millis";
         /**
          * The maximum age of log data used for shortcuts in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_STAT_AGE_MILLIS = "search_max_stat_age_millis";
         /**
          * The maximum age of log data used for source ranking in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS =
                 "search_max_source_event_age_millis";
         /**
          * The minimum number of impressions needed to rank a source in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING =
                 "search_min_impressions_for_source_ranking";
         /**
          * The minimum number of clicks needed to rank a source in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING =
                 "search_min_clicks_for_source_ranking";
         /**
          * The maximum number of shortcuts shown by GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_SHORTCUTS_RETURNED = "search_max_shortcuts_returned";
         /**
          * The size of the core thread pool for suggestion queries in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_QUERY_THREAD_CORE_POOL_SIZE =
                 "search_query_thread_core_pool_size";
         /**
          * The maximum size of the thread pool for suggestion queries in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_QUERY_THREAD_MAX_POOL_SIZE =
                 "search_query_thread_max_pool_size";
         /**
          * The size of the core thread pool for shortcut refreshing in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE =
                 "search_shortcut_refresh_core_pool_size";
         /**
          * The maximum size of the thread pool for shortcut refreshing in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE =
                 "search_shortcut_refresh_max_pool_size";
         /**
@@ -7650,12 +7994,14 @@
          * wait before terminating.
          * @hide
          */
+        @Readable
         public static final String SEARCH_THREAD_KEEPALIVE_SECONDS =
                 "search_thread_keepalive_seconds";
         /**
          * The maximum number of concurrent suggestion queries to each source.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT =
                 "search_per_source_concurrent_query_limit";
 
@@ -7664,24 +8010,28 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd";
 
         /**
          * Whether or not UMS auto-starts on UMS host detection. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_AUTOSTART = "mount_ums_autostart";
 
         /**
          * Whether or not a notification is displayed on UMS host detection. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_PROMPT = "mount_ums_prompt";
 
         /**
          * Whether or not a notification is displayed while UMS is enabled. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled";
 
         /**
@@ -7693,6 +8043,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String ANR_SHOW_BACKGROUND = "anr_show_background";
 
@@ -7702,6 +8053,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_FIRST_CRASH_DIALOG_DEV_OPTION =
                 "show_first_crash_dialog_dev_option";
@@ -7713,6 +8065,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
 
         /**
@@ -7723,6 +8076,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SELECTED_SPELL_CHECKER = "selected_spell_checker";
 
@@ -7735,6 +8089,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SELECTED_SPELL_CHECKER_SUBTYPE =
                 "selected_spell_checker_subtype";
@@ -7744,6 +8099,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SPELL_CHECKER_ENABLED = "spell_checker_enabled";
 
         /**
@@ -7756,6 +8112,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior";
 
         /**
@@ -7770,6 +8127,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MINIMAL_POST_PROCESSING_ALLOWED =
                 "minimal_post_processing_allowed";
 
@@ -7814,6 +8172,7 @@
          * @see #MATCH_CONTENT_FRAMERATE_ALWAYS
          * @hide
          */
+        @Readable
         public static final String MATCH_CONTENT_FRAME_RATE =
                 "match_content_frame_rate";
 
@@ -7845,6 +8204,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String INCALL_BACK_BUTTON_BEHAVIOR = "incall_back_button_behavior";
 
         /**
@@ -7870,6 +8230,7 @@
          * Whether the device should wake when the wake gesture sensor detects motion.
          * @hide
          */
+        @Readable
         public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled";
 
         /**
@@ -7877,6 +8238,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String DOZE_ENABLED = "doze_enabled";
 
         /**
@@ -7887,36 +8249,42 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DOZE_ALWAYS_ON = "doze_always_on";
 
         /**
          * Whether the device should pulse on pick up gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_PICK_UP_GESTURE = "doze_pulse_on_pick_up";
 
         /**
          * Whether the device should pulse on long press gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press";
 
         /**
          * Whether the device should pulse on double tap gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_DOUBLE_TAP_GESTURE = "doze_pulse_on_double_tap";
 
         /**
          * Whether the device should respond to the SLPI tap gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_TAP_SCREEN_GESTURE = "doze_tap_gesture";
 
         /**
          * Gesture that wakes up the display, showing some version of the lock screen.
          * @hide
          */
+        @Readable
         public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_screen_gesture";
 
         /**
@@ -7924,84 +8292,98 @@
          * {@link Display.STATE_DOZE}.
          * @hide
          */
+        @Readable
         public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
 
         /**
          * Whether the device should suppress the current doze configuration and disable dozing.
          * @hide
          */
+        @Readable
         public static final String SUPPRESS_DOZE = "suppress_doze";
 
         /**
          * Gesture that skips media.
          * @hide
          */
+        @Readable
         public static final String SKIP_GESTURE = "skip_gesture";
 
         /**
          * Count of successful gestures.
          * @hide
          */
+        @Readable
         public static final String SKIP_GESTURE_COUNT = "skip_gesture_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SKIP_TOUCH_COUNT = "skip_touch_count";
 
         /**
          * Direction to advance media for skip gesture
          * @hide
          */
+        @Readable
         public static final String SKIP_DIRECTION = "skip_gesture_direction";
 
         /**
          * Gesture that silences sound (alarms, notification, calls).
          * @hide
          */
+        @Readable
         public static final String SILENCE_GESTURE = "silence_gesture";
 
         /**
          * Count of successful silence alarms gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_ALARMS_GESTURE_COUNT = "silence_alarms_gesture_count";
 
         /**
          * Count of successful silence timer gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_TIMER_GESTURE_COUNT = "silence_timer_gesture_count";
 
         /**
          * Count of successful silence call gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_CALL_GESTURE_COUNT = "silence_call_gesture_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_ALARMS_TOUCH_COUNT = "silence_alarms_touch_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_TIMER_TOUCH_COUNT = "silence_timer_touch_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_CALL_TOUCH_COUNT = "silence_call_touch_count";
 
         /**
          * Number of successful "Motion Sense" tap gestures to pause media.
          * @hide
          */
+        @Readable
         public static final String AWARE_TAP_PAUSE_GESTURE_COUNT = "aware_tap_pause_gesture_count";
 
         /**
@@ -8009,12 +8391,14 @@
          * have been used.
          * @hide
          */
+        @Readable
         public static final String AWARE_TAP_PAUSE_TOUCH_COUNT = "aware_tap_pause_touch_count";
 
         /**
          * For user preference if swipe bottom to expand notification gesture enabled.
          * @hide
          */
+        @Readable
         public static final String SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED =
                 "swipe_bottom_to_notification_enabled";
 
@@ -8022,24 +8406,28 @@
          * For user preference if One-Handed Mode enabled.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_MODE_ENABLED = "one_handed_mode_enabled";
 
         /**
          * For user preference if One-Handed Mode timeout.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_MODE_TIMEOUT = "one_handed_mode_timeout";
 
         /**
          * For user taps app to exit One-Handed Mode.
          * @hide
          */
+        @Readable
         public static final String TAPS_APP_TO_EXIT = "taps_app_to_exit";
 
         /**
          * Internal use, one handed mode tutorial showed times.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_TUTORIAL_SHOW_COUNT =
                 "one_handed_tutorial_show_count";
 
@@ -8049,6 +8437,7 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE = "ui_night_mode";
 
         /**
@@ -8057,12 +8446,14 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_OVERRIDE_ON = "ui_night_mode_override_on";
 
         /**
          * The last computed night mode bool the last time the phone was on
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_LAST_COMPUTED = "ui_night_mode_last_computed";
 
         /**
@@ -8071,12 +8462,14 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_OVERRIDE_OFF = "ui_night_mode_override_off";
 
         /**
          * Whether screensavers are enabled.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ENABLED = "screensaver_enabled";
 
         /**
@@ -8086,6 +8479,7 @@
          * battery, or upon dock insertion (if SCREENSAVER_ACTIVATE_ON_DOCK is set to 1).
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_COMPONENTS = "screensaver_components";
 
         /**
@@ -8093,6 +8487,7 @@
          * when the device is inserted into a (desk) dock.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock";
 
         /**
@@ -8100,12 +8495,14 @@
          * when the screen times out when not on battery.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep";
 
         /**
          * If screensavers are enabled, the default screensaver component.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component";
 
         /**
@@ -8114,12 +8511,14 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
 
         /**
          * Whether NFC payment is handled by the foreground application or a default.
          * @hide
          */
+        @Readable
         public static final String NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground";
 
         /**
@@ -8127,6 +8526,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String SMS_DEFAULT_APPLICATION = "sms_default_application";
 
         /**
@@ -8134,6 +8534,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application";
 
         /**
@@ -8141,6 +8542,7 @@
          * application
          * @hide
          */
+        @Readable
         public static final String CALL_SCREENING_DEFAULT_COMPONENT =
                 "call_screening_default_component";
 
@@ -8151,6 +8553,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_ASSISTANCE_APPLICATION = "emergency_assistance_application";
 
         /**
@@ -8159,6 +8562,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled";
 
         /**
@@ -8167,6 +8571,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
 
         /**
@@ -8178,6 +8583,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled";
 
         /**
@@ -8189,7 +8595,7 @@
          *
          * @hide
          */
-
+        @Readable
         public static final String SHOW_ROTATION_SUGGESTIONS = "show_rotation_suggestions";
 
         /**
@@ -8216,6 +8622,7 @@
          * introduced to rotation suggestions.
          * @hide
          */
+        @Readable
         public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED =
                 "num_rotation_suggestions_accepted";
 
@@ -8228,6 +8635,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String ENABLED_NOTIFICATION_ASSISTANT =
                 "enabled_notification_assistant";
 
@@ -8241,6 +8649,7 @@
          */
         @Deprecated
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
 
         /**
@@ -8252,6 +8661,7 @@
          */
         @Deprecated
         @TestApi
+        @Readable
         public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES =
                 "enabled_notification_policy_access_packages";
 
@@ -8265,6 +8675,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
         public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
 
@@ -8273,6 +8684,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";
 
         /**
@@ -8280,6 +8692,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PRINT_SERVICE_SEARCH_URI = "print_service_search_uri";
 
         /**
@@ -8287,6 +8700,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PAYMENT_SERVICE_SEARCH_URI = "payment_service_search_uri";
 
         /**
@@ -8294,6 +8708,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_SERVICE_SEARCH_URI = "autofill_service_search_uri";
 
         /**
@@ -8302,6 +8717,7 @@
          * <p>
          * Type : int (0 to show hints, 1 to skip showing hints)
          */
+        @Readable
         public static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints";
 
         /**
@@ -8309,6 +8725,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String UNSAFE_VOLUME_MUSIC_ACTIVE_MS = "unsafe_volume_music_active_ms";
 
         /**
@@ -8319,6 +8736,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
                 "lock_screen_show_notifications";
 
@@ -8329,6 +8747,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS =
                 "lock_screen_show_silent_notifications";
 
@@ -8339,6 +8758,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTIFICATION_SNOOZE = "show_notification_snooze";
 
         /**
@@ -8347,6 +8767,7 @@
          * {@link android.net.Uri#encode(String)} and separated by ':'.
          * @hide
          */
+        @Readable
         public static final String TV_INPUT_HIDDEN_INPUTS = "tv_input_hidden_inputs";
 
         /**
@@ -8355,6 +8776,7 @@
          * and separated by ','. Each pair is separated by ':'.
          * @hide
          */
+        @Readable
         public static final String TV_INPUT_CUSTOM_LABELS = "tv_input_custom_labels";
 
         /**
@@ -8372,6 +8794,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TV_APP_USES_NON_SYSTEM_INPUTS = "tv_app_uses_non_system_inputs";
 
         /**
@@ -8381,6 +8804,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED =
                 "usb_audio_automatic_routing_disabled";
 
@@ -8396,6 +8820,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SLEEP_TIMEOUT = "sleep_timeout";
 
         /**
@@ -8410,12 +8835,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String ATTENTIVE_TIMEOUT = "attentive_timeout";
 
         /**
          * Controls whether double tap to wake is enabled.
          * @hide
          */
+        @Readable
         public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake";
 
         /**
@@ -8429,6 +8856,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ASSISTANT = "assistant";
 
         /**
@@ -8436,6 +8864,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";
 
         /**
@@ -8443,6 +8872,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_GESTURE_ENABLED = "emergency_gesture_enabled";
 
         /**
@@ -8450,6 +8880,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_GESTURE_SOUND_ENABLED =
                 "emergency_gesture_sound_enabled";
 
@@ -8459,6 +8890,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
                 "camera_double_tap_power_gesture_disabled";
 
@@ -8468,6 +8900,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED =
                 "camera_double_twist_to_flip_enabled";
 
@@ -8477,6 +8910,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled";
 
         /**
@@ -8492,6 +8926,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FLASHLIGHT_AVAILABLE = "flashlight_available";
 
         /**
@@ -8499,18 +8934,21 @@
          *
          * @hide
          */
+        @Readable
         public static final String FLASHLIGHT_ENABLED = "flashlight_enabled";
 
         /**
          * Whether or not face unlock is allowed on Keyguard.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_KEYGUARD_ENABLED = "face_unlock_keyguard_enabled";
 
         /**
          * Whether or not face unlock dismisses the keyguard.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_DISMISSES_KEYGUARD =
                 "face_unlock_dismisses_keyguard";
 
@@ -8518,6 +8956,7 @@
          * Whether or not media is shown automatically when bypassing as a heads up.
          * @hide
          */
+        @Readable
         public static final String SHOW_MEDIA_WHEN_BYPASSING =
                 "show_media_when_bypassing";
 
@@ -8526,6 +8965,7 @@
          * truth is obtained through the HAL.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_ATTENTION_REQUIRED =
                 "face_unlock_attention_required";
 
@@ -8534,6 +8974,7 @@
          * cached value, the source of truth is obtained through the HAL.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_DIVERSITY_REQUIRED =
                 "face_unlock_diversity_required";
 
@@ -8542,6 +8983,7 @@
          * Whether or not face unlock is allowed for apps (through BiometricPrompt).
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_APP_ENABLED = "face_unlock_app_enabled";
 
         /**
@@ -8551,6 +8993,7 @@
          * setConfirmationRequired API.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
                 "face_unlock_always_require_confirmation";
 
@@ -8565,12 +9008,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_RE_ENROLL = "face_unlock_re_enroll";
 
         /**
          * Whether or not debugging is enabled.
          * @hide
          */
+        @Readable
         public static final String BIOMETRIC_DEBUG_ENABLED =
                 "biometric_debug_enabled";
 
@@ -8579,6 +9024,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled";
 
         /**
@@ -8586,6 +9032,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
 
         /**
@@ -8593,6 +9040,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED =
                 "assist_gesture_silence_alerts_enabled";
 
@@ -8601,6 +9049,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_WAKE_ENABLED =
                 "assist_gesture_wake_enabled";
 
@@ -8612,36 +9061,42 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
 
         /**
          * Control whether Trust Agents are in active unlock or extend unlock mode.
          * @hide
          */
+        @Readable
         public static final String TRUST_AGENTS_EXTEND_UNLOCK = "trust_agents_extend_unlock";
 
         /**
          * Control whether the screen locks when trust is lost.
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_WHEN_TRUST_LOST = "lock_screen_when_trust_lost";
 
         /**
          * Control whether Night display is currently activated.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_ACTIVATED = "night_display_activated";
 
         /**
          * Control whether Night display will automatically activate/deactivate.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode";
 
         /**
          * Control the color temperature of Night Display, represented in Kelvin.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE =
                 "night_display_color_temperature";
 
@@ -8650,6 +9105,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_CUSTOM_START_TIME =
                 "night_display_custom_start_time";
 
@@ -8658,6 +9114,7 @@
          * Represented as milliseconds from midnight (e.g. 21600000 == 6am).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
 
         /**
@@ -8666,6 +9123,7 @@
          * legacy cases, this is represented by the time in milliseconds (since epoch).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME =
                 "night_display_last_activated_time";
 
@@ -8673,6 +9131,7 @@
          * Control whether display white balance is currently enabled.
          * @hide
          */
+        @Readable
         public static final String DISPLAY_WHITE_BALANCE_ENABLED = "display_white_balance_enabled";
 
         /**
@@ -8683,6 +9142,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
 
         /**
@@ -8692,6 +9152,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VR_DISPLAY_MODE = "vr_display_mode";
 
         /**
@@ -8725,6 +9186,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CARRIER_APPS_HANDLED = "carrier_apps_handled";
 
         /**
@@ -8732,6 +9194,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MANAGED_PROFILE_CONTACT_REMOTE_SEARCH =
                 "managed_profile_contact_remote_search";
 
@@ -8740,6 +9203,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CROSS_PROFILE_CALENDAR_ENABLED =
                 "cross_profile_calendar_enabled";
 
@@ -8748,6 +9212,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_ENABLED =
                 "automatic_storage_manager_enabled";
 
@@ -8756,6 +9221,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN =
                 "automatic_storage_manager_days_to_retain";
 
@@ -8771,6 +9237,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED =
                 "automatic_storage_manager_bytes_cleared";
 
@@ -8779,6 +9246,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_LAST_RUN =
                 "automatic_storage_manager_last_run";
         /**
@@ -8788,6 +9256,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY =
                 "automatic_storage_manager_turned_off_by_policy";
 
@@ -8795,6 +9264,7 @@
          * Whether SystemUI navigation keys is enabled.
          * @hide
          */
+        @Readable
         public static final String SYSTEM_NAVIGATION_KEYS_ENABLED =
                 "system_navigation_keys_enabled";
 
@@ -8803,6 +9273,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String QS_TILES = "sysui_qs_tiles";
 
         /**
@@ -8813,6 +9284,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONTROLS_ENABLED = "controls_enabled";
 
         /**
@@ -8822,6 +9294,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String POWER_MENU_LOCKED_SHOW_CONTENT =
                 "power_menu_locked_show_content";
 
@@ -8831,18 +9304,21 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled";
 
         /**
          * Has this pairable device been paired or upgraded from a previously paired system.
          * @hide
          */
+        @Readable
         public static final String DEVICE_PAIRED = "device_paired";
 
         /**
          * Specifies additional package name for broadcasting the CMAS messages.
          * @hide
          */
+        @Readable
         public static final String CMAS_ADDITIONAL_BROADCAST_PKG = "cmas_additional_broadcast_pkg";
 
         /**
@@ -8852,6 +9328,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String NOTIFICATION_BADGING = "notification_badging";
 
         /**
@@ -8861,6 +9338,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_HISTORY_ENABLED = "notification_history_enabled";
 
         /**
@@ -8869,6 +9347,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String BUBBLE_IMPORTANT_CONVERSATIONS
                 = "bubble_important_conversations";
 
@@ -8878,18 +9357,21 @@
          *
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl";
 
         /**
          * Comma separated list of QS tiles that have been auto-added already.
          * @hide
          */
+        @Readable
         public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles";
 
         /**
          * Whether the Lockdown button should be shown in the power menu.
          * @hide
          */
+        @Readable
         public static final String LOCKDOWN_IN_POWER_MENU = "lockdown_in_power_menu";
 
         /**
@@ -8917,6 +9399,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String BACKUP_MANAGER_CONSTANTS = "backup_manager_constants";
 
 
@@ -8934,6 +9417,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String BACKUP_LOCAL_TRANSPORT_PARAMETERS =
                 "backup_local_transport_parameters";
 
@@ -8942,6 +9426,7 @@
          * the user is driving.
          * @hide
          */
+        @Readable
         public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving";
 
         /**
@@ -8951,6 +9436,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
 
         /** @hide */
@@ -8967,6 +9453,7 @@
          * The number of times (integer) the user has manually enabled battery saver.
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MANUAL_ACTIVATION_COUNT =
                 "low_power_manual_activation_count";
 
@@ -8976,6 +9463,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_WARNING_ACKNOWLEDGED =
                 "low_power_warning_acknowledged";
 
@@ -8984,6 +9472,7 @@
          * suppressed.
          * @hide
          */
+        @Readable
         public static final String SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION =
                 "suppress_auto_battery_saver_suggestion";
 
@@ -8992,6 +9481,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE =
                 "packages_to_clear_data_before_full_restore";
 
@@ -9000,6 +9490,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS =
                 "location_access_check_interval_millis";
 
@@ -9008,6 +9499,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS =
                 "location_access_check_delay_millis";
 
@@ -9017,6 +9509,7 @@
          */
         @SystemApi
         @Deprecated
+        @Readable
         public static final String LOCATION_PERMISSIONS_UPGRADE_TO_Q_MODE =
                 "location_permissions_upgrade_to_q_mode";
 
@@ -9025,6 +9518,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTO_REVOKE_DISABLED = "auto_revoke_disabled";
 
         /**
@@ -9035,6 +9529,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES =
                 "theme_customization_overlay_packages";
 
@@ -9045,6 +9540,7 @@
          *  2 = fully gestural
          * @hide
          */
+        @Readable
         public static final String NAVIGATION_MODE =
                 "navigation_mode";
 
@@ -9052,6 +9548,7 @@
          * Scale factor for the back gesture inset size on the left side of the screen.
          * @hide
          */
+        @Readable
         public static final String BACK_GESTURE_INSET_SCALE_LEFT =
                 "back_gesture_inset_scale_left";
 
@@ -9059,6 +9556,7 @@
          * Scale factor for the back gesture inset size on the right side of the screen.
          * @hide
          */
+        @Readable
         public static final String BACK_GESTURE_INSET_SCALE_RIGHT =
                 "back_gesture_inset_scale_right";
 
@@ -9068,30 +9566,35 @@
          * No VALIDATOR as this setting will not be backed up.
          * @hide
          */
+        @Readable
         public static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
 
         /**
          * Controls whether aware is enabled.
          * @hide
          */
+        @Readable
         public static final String AWARE_ENABLED = "aware_enabled";
 
         /**
          * Controls whether aware_lock is enabled.
          * @hide
          */
+        @Readable
         public static final String AWARE_LOCK_ENABLED = "aware_lock_enabled";
 
         /**
          * Controls whether tap gesture is enabled.
          * @hide
          */
+        @Readable
         public static final String TAP_GESTURE = "tap_gesture";
 
         /**
          * Controls whether the people strip is enabled.
          * @hide
          */
+        @Readable
         public static final String PEOPLE_STRIP = "people_strip";
 
         /**
@@ -9101,6 +9604,7 @@
          * @see Settings.Global#SHOW_MEDIA_ON_QUICK_SETTINGS
          * @hide
          */
+        @Readable
         public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
 
         /**
@@ -9109,6 +9613,7 @@
          * @see Settings.Secure#MEDIA_CONTROLS_RESUME
          * @hide
          */
+        @Readable
         public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked";
 
         /**
@@ -9120,6 +9625,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_MAGNIFICATION_MODE =
                 "accessibility_magnification_mode";
 
@@ -9155,6 +9661,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_MAGNIFICATION_CAPABILITY =
                 "accessibility_magnification_capability";
 
@@ -9164,6 +9671,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT =
                 "accessibility_show_window_magnification_prompt";
 
@@ -9180,6 +9688,7 @@
          * @see #ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_MODE =
                 "accessibility_button_mode";
 
@@ -9208,6 +9717,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_SIZE =
                 "accessibility_floating_menu_size";
 
@@ -9220,6 +9730,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_ICON_TYPE =
                 "accessibility_floating_menu_icon_type";
 
@@ -9229,6 +9740,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_OPACITY =
                 "accessibility_floating_menu_opacity";
 
@@ -9237,6 +9749,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled";
 
         /**
@@ -9248,6 +9761,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String[] LEGACY_RESTORE_SETTINGS = {
                 ENABLED_NOTIFICATION_LISTENERS,
                 ENABLED_NOTIFICATION_ASSISTANT,
@@ -9259,6 +9773,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_HANDLES_LEARNING_TIME_ELAPSED_MILLIS =
                 "reminder_exp_learning_time_elapsed";
 
@@ -9267,6 +9782,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_HANDLES_LEARNING_EVENT_COUNT =
                 "reminder_exp_learning_event_count";
 
@@ -9380,6 +9896,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
 
         /**
@@ -9388,6 +9905,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String ADD_USERS_WHEN_LOCKED = "add_users_when_locked";
 
         /**
@@ -9395,6 +9913,7 @@
          * <p>1 = apply ramping ringer
          * <p>0 = do not apply ramping ringer
          */
+        @Readable
         public static final String APPLY_RAMPING_RINGER = "apply_ramping_ringer";
 
         /**
@@ -9406,12 +9925,14 @@
          * No longer used. Should be removed once all dependencies have been updated.
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED =
                 "enable_accessibility_global_gesture_enabled";
 
         /**
          * Whether Airplane Mode is on.
          */
+        @Readable
         public static final String AIRPLANE_MODE_ON = "airplane_mode_on";
 
         /**
@@ -9419,30 +9940,36 @@
          * {@hide}
          */
         @SystemApi
+        @Readable
         public static final String THEATER_MODE_ON = "theater_mode_on";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Bluetooth radio.
          */
+        @Readable
         public static final String RADIO_BLUETOOTH = "bluetooth";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Wi-Fi radio.
          */
+        @Readable
         public static final String RADIO_WIFI = "wifi";
 
         /**
          * {@hide}
          */
+        @Readable
         public static final String RADIO_WIMAX = "wimax";
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Cellular radio.
          */
+        @Readable
         public static final String RADIO_CELL = "cell";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify NFC radio.
          */
+        @Readable
         public static final String RADIO_NFC = "nfc";
 
         /**
@@ -9450,6 +9977,7 @@
          * is on. This overrides WIFI_ON and BLUETOOTH_ON, if Wi-Fi and bluetooth are
          * included in the comma separated list.
          */
+        @Readable
         public static final String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
 
         /**
@@ -9461,6 +9989,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
 
         /**
@@ -9468,6 +9997,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLUETOOTH_CLASS_OF_DEVICE = "bluetooth_class_of_device";
 
         /**
@@ -9475,6 +10005,7 @@
          * See {@link android.bluetooth.BluetoothProfile}.
          * {@hide}
          */
+        @Readable
         public static final String BLUETOOTH_DISABLED_PROFILES = "bluetooth_disabled_profiles";
 
         /**
@@ -9487,6 +10018,7 @@
          *   "00:11:22,0;01:02:03:04,2"
          * @hide
          */
+        @Readable
        public static final String BLUETOOTH_INTEROPERABILITY_LIST = "bluetooth_interoperability_list";
 
         /**
@@ -9499,6 +10031,7 @@
          * @deprecated This is no longer used or set by the platform.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_SLEEP_POLICY = "wifi_sleep_policy";
 
         /**
@@ -9530,60 +10063,70 @@
          * Value to specify if the user prefers the date, time and time zone
          * to be automatically fetched from the network (NITZ). 1=yes, 0=no
          */
+        @Readable
         public static final String AUTO_TIME = "auto_time";
 
         /**
          * Value to specify if the user prefers the time zone
          * to be automatically fetched from the network (NITZ). 1=yes, 0=no
          */
+        @Readable
         public static final String AUTO_TIME_ZONE = "auto_time_zone";
 
         /**
          * URI for the car dock "in" event sound.
          * @hide
          */
+        @Readable
         public static final String CAR_DOCK_SOUND = "car_dock_sound";
 
         /**
          * URI for the car dock "out" event sound.
          * @hide
          */
+        @Readable
         public static final String CAR_UNDOCK_SOUND = "car_undock_sound";
 
         /**
          * URI for the desk dock "in" event sound.
          * @hide
          */
+        @Readable
         public static final String DESK_DOCK_SOUND = "desk_dock_sound";
 
         /**
          * URI for the desk dock "out" event sound.
          * @hide
          */
+        @Readable
         public static final String DESK_UNDOCK_SOUND = "desk_undock_sound";
 
         /**
          * Whether to play a sound for dock events.
          * @hide
          */
+        @Readable
         public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
 
         /**
          * Whether to play a sound for dock events, only when an accessibility service is on.
          * @hide
          */
+        @Readable
         public static final String DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY = "dock_sounds_enabled_when_accessbility";
 
         /**
          * URI for the "device locked" (keyguard shown) sound.
          * @hide
          */
+        @Readable
         public static final String LOCK_SOUND = "lock_sound";
 
         /**
          * URI for the "device unlocked" sound.
          * @hide
          */
+        @Readable
         public static final String UNLOCK_SOUND = "unlock_sound";
 
         /**
@@ -9591,24 +10134,28 @@
          * state without unlocking.
          * @hide
          */
+        @Readable
         public static final String TRUSTED_SOUND = "trusted_sound";
 
         /**
          * URI for the low battery sound file.
          * @hide
          */
+        @Readable
         public static final String LOW_BATTERY_SOUND = "low_battery_sound";
 
         /**
          * Whether to play a sound for low-battery alerts.
          * @hide
          */
+        @Readable
         public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
 
         /**
          * URI for the "wireless charging started" sound.
          * @hide
          */
+        @Readable
         public static final String WIRELESS_CHARGING_STARTED_SOUND =
                 "wireless_charging_started_sound";
 
@@ -9616,6 +10163,7 @@
          * URI for "wired charging started" sound.
          * @hide
          */
+        @Readable
         public static final String CHARGING_STARTED_SOUND = "charging_started_sound";
 
         /**
@@ -9645,6 +10193,7 @@
          * </ul>
          * These values can be OR-ed together.
          */
+        @Readable
         public static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
 
         /**
@@ -9652,6 +10201,7 @@
          * in the power menu.
          * @hide
          */
+        @Readable
         public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
 
         /**
@@ -9660,6 +10210,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CUSTOM_BUGREPORT_HANDLER_APP = "custom_bugreport_handler_app";
 
         /**
@@ -9668,29 +10219,34 @@
          *
          * @hide
          */
+        @Readable
         public static final String CUSTOM_BUGREPORT_HANDLER_USER = "custom_bugreport_handler_user";
 
         /**
          * Whether ADB over USB is enabled.
          */
+        @Readable
         public static final String ADB_ENABLED = "adb_enabled";
 
         /**
          * Whether ADB over Wifi is enabled.
          * @hide
          */
+        @Readable
         public static final String ADB_WIFI_ENABLED = "adb_wifi_enabled";
 
         /**
          * Whether Views are allowed to save their attribute data.
          * @hide
          */
+        @Readable
         public static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";
 
         /**
          * Which application package is allowed to save View attribute data.
          * @hide
          */
+        @Readable
         public static final String DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE =
                 "debug_view_attributes_application_package";
 
@@ -9698,12 +10254,14 @@
          * Whether assisted GPS should be enabled or not.
          * @hide
          */
+        @Readable
         public static final String ASSISTED_GPS_ENABLED = "assisted_gps_enabled";
 
         /**
          * Whether bluetooth is enabled/disabled
          * 0=disabled. 1=enabled.
          */
+        @Readable
         public static final String BLUETOOTH_ON = "bluetooth_on";
 
         /**
@@ -9712,6 +10270,7 @@
          *                            1 = CDMA Cell Broadcast SMS enabled
          * @hide
          */
+        @Readable
         public static final String CDMA_CELL_BROADCAST_SMS =
                 "cdma_cell_broadcast_sms";
 
@@ -9721,6 +10280,7 @@
          *                       2 = Roaming on any networks
          * @hide
          */
+        @Readable
         public static final String CDMA_ROAMING_MODE = "roaming_settings";
 
         /**
@@ -9728,6 +10288,7 @@
          *                                1 = NV
          * @hide
          */
+        @Readable
         public static final String CDMA_SUBSCRIPTION_MODE = "subscription_mode";
 
         /**
@@ -9737,52 +10298,56 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEFAULT_RESTRICT_BACKGROUND_DATA =
                 "default_restrict_background_data";
 
         /** Inactivity timeout to track mobile data activity.
-        *
-        * If set to a positive integer, it indicates the inactivity timeout value in seconds to
-        * infer the data activity of mobile network. After a period of no activity on mobile
-        * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
-        * intent is fired to indicate a transition of network status from "active" to "idle". Any
-        * subsequent activity on mobile networks triggers the firing of {@code
-        * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
-        *
-        * 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";
+         *
+         * If set to a positive integer, it indicates the inactivity timeout value in seconds to
+         * infer the data activity of mobile network. After a period of no activity on mobile
+         * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
+         * intent is fired to indicate a transition of network status from "active" to "idle". Any
+         * subsequent activity on mobile networks triggers the firing of {@code
+         * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
+         *
+         * Network activity refers to transmitting or receiving data on the network interfaces.
+         *
+         * Tracking is disabled if set to zero or negative value.
+         *
+         * @hide
+         */
+        @Readable
+        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";
+        /** Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
+         * but for Wifi network.
+         * @hide
+         */
+        @Readable
+        public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
 
-       /**
-        * Whether or not data roaming is enabled. (0 = false, 1 = true)
-        */
-       public static final String DATA_ROAMING = "data_roaming";
+        /**
+         * Whether or not data roaming is enabled. (0 = false, 1 = true)
+         */
+        @Readable
+        public static final String DATA_ROAMING = "data_roaming";
 
-       /**
-        * The value passed to a Mobile DataConnection via bringUp which defines the
-        * number of retries to preform when setting up the initial connection. The default
-        * value defined in DataConnectionTrackerBase#DEFAULT_MDC_INITIAL_RETRY is currently 1.
-        * @hide
-        */
-       public static final String MDC_INITIAL_MAX_RETRY = "mdc_initial_max_retry";
+        /**
+         * The value passed to a Mobile DataConnection via bringUp which defines the
+         * number of retries to preform when setting up the initial connection. The default
+         * value defined in DataConnectionTrackerBase#DEFAULT_MDC_INITIAL_RETRY is currently 1.
+         * @hide
+         */
+        public static final String MDC_INITIAL_MAX_RETRY = "mdc_initial_max_retry";
 
-       /**
-        * Whether any package can be on external storage. When this is true, any
-        * package, regardless of manifest values, is a candidate for installing
-        * or moving onto external storage. (0 = false, 1 = true)
-        * @hide
-        */
-       public static final String FORCE_ALLOW_ON_EXTERNAL = "force_allow_on_external";
+        /**
+         * Whether any package can be on external storage. When this is true, any
+         * package, regardless of manifest values, is a candidate for installing
+         * or moving onto external storage. (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String FORCE_ALLOW_ON_EXTERNAL = "force_allow_on_external";
 
         /**
          * The default SM-DP+ configured for this device.
@@ -9796,6 +10361,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
 
         /**
@@ -9807,6 +10373,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_PROVISIONED = "euicc_provisioned";
 
         /**
@@ -9822,6 +10389,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_SUPPORTED_COUNTRIES = "euicc_supported_countries";
 
         /**
@@ -9837,6 +10405,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_UNSUPPORTED_COUNTRIES = "euicc_unsupported_countries";
 
         /**
@@ -9845,6 +10414,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES
                 = "force_resizable_activities";
 
@@ -9852,6 +10422,7 @@
          * Whether to enable experimental freeform support for windows.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT
                 = "enable_freeform_support";
 
@@ -9859,23 +10430,42 @@
          * Whether to enable experimental desktop mode on secondary displays.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS =
                 "force_desktop_mode_on_external_displays";
 
         /**
          * Whether to allow non-resizable apps to be freeform.
+         *
+         * TODO(b/176061101) remove after update all usages
+         * @deprecated use {@link #DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW}
          * @hide
          */
+        @Deprecated
+        @Readable
         public static final String DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM =
                 "enable_sizecompat_freeform";
 
         /**
+         * Whether to allow non-resizable apps to be shown in multi-window. The app will be
+         * letterboxed if the request orientation is not met, and will be shown in size-compat
+         * mode if the container size has changed.
+         * @hide
+         */
+        @TestApi
+        @Readable
+        @SuppressLint("NoSettingsProvider")
+        public static final String DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW =
+                "enable_non_resizable_multi_window";
+
+        /**
          * If true, shadows drawn around the window will be rendered by the system compositor. If
          * false, shadows will be drawn by the client by setting an elevation on the root view and
          * the contents will be inset by the surface insets.
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR =
                 "render_shadows_in_compositor";
 
@@ -9884,6 +10474,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_USE_BLAST_ADAPTER_VR =
                 "use_blast_adapter_vr";
 
@@ -9892,6 +10483,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_USE_BLAST_ADAPTER_SV =
                 "use_blast_adapter_sv";
 
@@ -9901,21 +10493,24 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH =
                 "wm_display_settings_path";
 
-       /**
+        /**
         * Whether user has enabled development settings.
         */
-       public static final String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
+        @Readable
+        public static final String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
 
-       /**
+        /**
         * Whether the device has been provisioned (0 = false, 1 = true).
         * <p>On a multiuser device with a separate system user, the screen may be locked
         * as soon as this is set to true and further activities cannot be launched on the
         * system user unless they are marked to show over keyguard.
         */
-       public static final String DEVICE_PROVISIONED = "device_provisioned";
+        @Readable
+        public static final String DEVICE_PROVISIONED = "device_provisioned";
 
         /**
          * Indicates whether mobile data should be allowed while the device is being provisioned.
@@ -9928,52 +10523,58 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEVICE_PROVISIONING_MOBILE_DATA_ENABLED =
                 "device_provisioning_mobile_data";
 
-       /**
+        /**
         * The saved value for WindowManagerService.setForcedDisplaySize().
         * Two integers separated by a comma.  If unset, then use the real display size.
         * @hide
         */
-       public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
+        @Readable
+        public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
 
-       /**
+        /**
         * The saved value for WindowManagerService.setForcedDisplayScalingMode().
         * 0 or unset if scaling is automatic, 1 if scaling is disabled.
         * @hide
         */
-       public static final String DISPLAY_SCALING_FORCE = "display_scaling_force";
+        @Readable
+        public static final String DISPLAY_SCALING_FORCE = "display_scaling_force";
 
-       /**
+        /**
         * The maximum size, in bytes, of a download that the download manager will transfer over
         * a non-wifi connection.
         * @hide
         */
-       public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE =
+        @Readable
+        public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE =
                "download_manager_max_bytes_over_mobile";
 
-       /**
+        /**
         * The recommended maximum size, in bytes, of a download that the download manager should
         * transfer over a non-wifi connection. Over this size, the use will be warned, but will
         * have the option to start the download over the mobile connection anyway.
         * @hide
         */
-       public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE =
+        @Readable
+        public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE =
                "download_manager_recommended_max_bytes_over_mobile";
 
-       /**
+        /**
         * @deprecated Use {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS} instead
         */
-       @Deprecated
-       public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS;
+        @Deprecated
+        public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS;
 
-       /**
+        /**
         * Whether HDMI control shall be enabled. If disabled, no CEC/MHL command will be
         * sent or processed. (0 = false, 1 = true)
         * @hide
         */
-       public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
+        @Readable
+        public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
 
         /**
          * Controls whether volume control commands via HDMI CEC are enabled. (0 = false, 1 =
@@ -10009,16 +10610,18 @@
          * @hide
          * @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)
          */
+        @Readable
         public static final String HDMI_CONTROL_VOLUME_CONTROL_ENABLED =
                 "hdmi_control_volume_control_enabled";
 
-       /**
+        /**
         * Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
         * system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
         * be played on AVR instead of TV spaeker. If disabled, the system audio mode will never be
         * activated.
         * @hide
         */
+        @Readable
         public static final String HDMI_SYSTEM_AUDIO_CONTROL_ENABLED =
                 "hdmi_system_audio_control_enabled";
 
@@ -10028,6 +10631,7 @@
          * disabled, you can only switch the input via controls on this device.
          * @hide
          */
+        @Readable
         public static final String HDMI_CEC_SWITCH_ENABLED =
                 "hdmi_cec_switch_enabled";
 
@@ -10035,6 +10639,7 @@
          * HDMI CEC version to use. Defaults to v1.4b.
          * @hide
          */
+        @Readable
         public static final String HDMI_CEC_VERSION =
                 "hdmi_cec_version";
 
@@ -10044,6 +10649,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_AUTO_WAKEUP_ENABLED =
                 "hdmi_control_auto_wakeup_enabled";
 
@@ -10053,6 +10659,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED =
                 "hdmi_control_auto_device_off_enabled";
 
@@ -10074,6 +10681,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_SEND_STANDBY_ON_SLEEP =
                 "hdmi_control_send_standby_on_sleep";
 
@@ -10081,6 +10689,7 @@
          * Whether or not media is shown automatically when bypassing as a heads up.
          * @hide
          */
+        @Readable
         public static final String SHOW_MEDIA_ON_QUICK_SETTINGS =
                 "qs_media_player";
 
@@ -10090,6 +10699,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS =
                 "location_background_throttle_interval_ms";
 
@@ -10098,6 +10708,7 @@
          * to request.
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS =
                 "location_background_throttle_proximity_alert_interval_ms";
 
@@ -10105,6 +10716,7 @@
          * Packages that are whitelisted for background throttling (throttling will not be applied).
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST =
             "location_background_throttle_package_whitelist";
 
@@ -10114,6 +10726,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST =
                 "location_ignore_settings_package_whitelist";
 
@@ -10122,23 +10735,26 @@
         * (0 = false, 1 = true)
         * @hide
         */
-       public static final String MHL_INPUT_SWITCHING_ENABLED = "mhl_input_switching_enabled";
+        @Readable
+        public static final String MHL_INPUT_SWITCHING_ENABLED = "mhl_input_switching_enabled";
 
-       /**
+        /**
         * Whether TV will charge the mobile device connected at MHL port. (0 = false, 1 = true)
         * @hide
         */
-       public static final String MHL_POWER_CHARGE_ENABLED = "mhl_power_charge_enabled";
+        @Readable
+        public static final String MHL_POWER_CHARGE_ENABLED = "mhl_power_charge_enabled";
 
-       /**
+        /**
         * Whether mobile data connections are allowed by the user.  See
         * ConnectivityManager for more info.
         * @hide
         */
-       @UnsupportedAppUsage
-       public static final String MOBILE_DATA = "mobile_data";
+        @UnsupportedAppUsage
+        @Readable
+        public static final String MOBILE_DATA = "mobile_data";
 
-       /**
+        /**
         * Whether the mobile data connection should remain active even when higher
         * priority networks like WiFi are active, to help make network switching faster.
         *
@@ -10147,7 +10763,8 @@
         * (0 = disabled, 1 = enabled)
         * @hide
         */
-       public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
+        @Readable
+        public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
         /**
          * Whether the wifi data connection should remain active even when higher
@@ -10160,195 +10777,249 @@
          * (0 = disabled, 1 = enabled)
          * @hide
          */
+        @Readable
         public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested";
 
         /**
          * Size of the event buffer for IP connectivity metrics.
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_METRICS_BUFFER_SIZE =
               "connectivity_metrics_buffer_size";
 
-       /** {@hide} */
-       public static final String NETSTATS_ENABLED = "netstats_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_POLL_INTERVAL = "netstats_poll_interval";
-       /** {@hide} */
-       @Deprecated
-       public static final String NETSTATS_TIME_CACHE_MAX_AGE = "netstats_time_cache_max_age";
-       /** {@hide} */
-       public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED = "netstats_combine_subtype_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_ENABLED = "netstats_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_POLL_INTERVAL = "netstats_poll_interval";
+        /**
+         * @deprecated
+         * {@hide}
+         */
+        @Deprecated
+        @Readable
+        public static final String NETSTATS_TIME_CACHE_MAX_AGE = "netstats_time_cache_max_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED =
+                "netstats_combine_subtype_enabled";
 
-       /** {@hide} */
-       public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_PERSIST_BYTES = "netstats_dev_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_ROTATE_AGE = "netstats_dev_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_DELETE_AGE = "netstats_dev_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_PERSIST_BYTES = "netstats_dev_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_ROTATE_AGE = "netstats_dev_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_DELETE_AGE = "netstats_dev_delete_age";
 
-       /** {@hide} */
-       public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_UID_PERSIST_BYTES = "netstats_uid_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_UID_ROTATE_AGE = "netstats_uid_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_UID_DELETE_AGE = "netstats_uid_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_PERSIST_BYTES = "netstats_uid_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_ROTATE_AGE = "netstats_uid_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_DELETE_AGE = "netstats_uid_delete_age";
 
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_BUCKET_DURATION = "netstats_uid_tag_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_PERSIST_BYTES = "netstats_uid_tag_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_ROTATE_AGE = "netstats_uid_tag_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_BUCKET_DURATION =
+                "netstats_uid_tag_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_PERSIST_BYTES =
+                "netstats_uid_tag_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_ROTATE_AGE = "netstats_uid_tag_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
 
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH = "netpolicy_quota_frac_multipath";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH =
+                "netpolicy_quota_frac_multipath";
 
-       /** {@hide} */
-       public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
 
-       /**
+        /**
         * User preference for which network(s) should be used. Only the
         * connectivity service should touch this.
         */
-       public static final String NETWORK_PREFERENCE = "network_preference";
+        @Readable
+        public static final String NETWORK_PREFERENCE = "network_preference";
 
-       /**
+        /**
         * Which package name to use for network scoring. If null, or if the package is not a valid
         * scorer app, external network scores will neither be requested nor accepted.
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String NETWORK_SCORER_APP = "network_scorer_app";
+        @Readable
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public static final String NETWORK_SCORER_APP = "network_scorer_app";
 
         /**
          * Whether night display forced auto mode is available.
          * 0 = unavailable, 1 = available.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE =
                 "night_display_forced_auto_mode_available";
 
-       /**
+        /**
         * If the NITZ_UPDATE_DIFF time is exceeded then an automatic adjustment
         * to SystemClock will be allowed even if NITZ_UPDATE_SPACING has not been
         * exceeded.
         * @hide
         */
-       public static final String NITZ_UPDATE_DIFF = "nitz_update_diff";
+        @Readable
+        public static final String NITZ_UPDATE_DIFF = "nitz_update_diff";
 
-       /**
+        /**
         * The length of time in milli-seconds that automatic small adjustments to
         * SystemClock are ignored if NITZ_UPDATE_DIFF is not exceeded.
         * @hide
         */
-       public static final String NITZ_UPDATE_SPACING = "nitz_update_spacing";
+        @Readable
+        public static final String NITZ_UPDATE_SPACING = "nitz_update_spacing";
 
-       /** Preferred NTP server. {@hide} */
-       public static final String NTP_SERVER = "ntp_server";
-       /** Timeout in milliseconds to wait for NTP server. {@hide} */
-       public static final String NTP_TIMEOUT = "ntp_timeout";
+        /** Preferred NTP server. {@hide} */
+        @Readable
+        public static final String NTP_SERVER = "ntp_server";
+        /** Timeout in milliseconds to wait for NTP server. {@hide} */
+        @Readable
+        public static final String NTP_TIMEOUT = "ntp_timeout";
 
-       /** {@hide} */
-       public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
+        /** {@hide} */
+        @Readable
+        public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
 
         /**
          * Whether or not Settings should enable psd API.
          * {@hide}
          */
+        @Readable
         public static final String SETTINGS_USE_PSD_API = "settings_use_psd_api";
 
         /**
          * Whether or not Settings should enable external provider API.
          * {@hide}
          */
+        @Readable
         public static final String SETTINGS_USE_EXTERNAL_PROVIDER_API =
                 "settings_use_external_provider_api";
 
-       /**
+        /**
         * Sample validity in seconds to configure for the system DNS resolver.
         * {@hide}
         */
-       public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
+        @Readable
+        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 =
+        @Readable
+        public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
                 "dns_resolver_success_threshold_percent";
 
-       /**
+        /**
         * 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";
+        @Readable
+        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";
+        @Readable
+        public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
 
-       /**
+        /**
         * Whether to disable the automatic scheduling of system updates.
         * 1 = system updates won't be automatically scheduled (will always
         * present notification instead).
         * 0 = system updates will be automatically scheduled. (default)
         * @hide
         */
-       @SystemApi
-       public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
+        @SystemApi
+        @Readable
+        public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
 
-       /** Timeout for package verification.
+        /** Timeout for package verification.
         * @hide */
-       public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
+        @Readable
+        public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
 
         /** Timeout for app integrity verification.
          * @hide */
+        @Readable
         public static final String APP_INTEGRITY_VERIFICATION_TIMEOUT =
                 "app_integrity_verification_timeout";
 
-       /** Default response code for package verification.
+        /** Default response code for package verification.
         * @hide */
-       public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
+        @Readable
+        public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
 
-       /**
+        /**
         * Show package verification setting in the Settings app.
         * 1 = show (default)
         * 0 = hide
         * @hide
         */
-       public static final String PACKAGE_VERIFIER_SETTING_VISIBLE = "verifier_setting_visible";
+        @Readable
+        public static final String PACKAGE_VERIFIER_SETTING_VISIBLE = "verifier_setting_visible";
 
-       /**
+        /**
         * Run package verification on apps installed through ADB/ADT/USB
         * 1 = perform package verification on ADB installs (default)
         * 0 = bypass package verification on ADB installs
         * @hide
         */
-       public static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
+        @Readable
+        public static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
 
         /**
          * Run integrity checks for integrity rule providers.
@@ -10356,117 +11027,131 @@
          * 1 = perform integrity verification on installs from rule providers
          * @hide
          */
+        @Readable
         public static final String INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER =
                 "verify_integrity_for_rule_provider";
 
-       /**
+        /**
         * Time since last fstrim (milliseconds) after which we force one to happen
         * during device startup.  If unset, the default is 3 days.
         * @hide
         */
-       public static final String FSTRIM_MANDATORY_INTERVAL = "fstrim_mandatory_interval";
+        @Readable
+        public static final String FSTRIM_MANDATORY_INTERVAL = "fstrim_mandatory_interval";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface when screen is on, to detect possible data
         * connection problems.
         * @hide
         */
-       public static final String PDP_WATCHDOG_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_POLL_INTERVAL_MS =
                "pdp_watchdog_poll_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface when screen is off, to detect possible data
         * connection problems.
         * @hide
         */
-       public static final String PDP_WATCHDOG_LONG_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_LONG_POLL_INTERVAL_MS =
                "pdp_watchdog_long_poll_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface after {@link #PDP_WATCHDOG_TRIGGER_PACKET_COUNT}
         * outgoing packets has been reached without incoming packets.
         * @hide
         */
-       public static final String PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS =
                "pdp_watchdog_error_poll_interval_ms";
 
-       /**
+        /**
         * The number of outgoing packets sent without seeing an incoming packet
         * that triggers a countdown (of {@link #PDP_WATCHDOG_ERROR_POLL_COUNT}
         * device is logged to the event log
         * @hide
         */
-       public static final String PDP_WATCHDOG_TRIGGER_PACKET_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_TRIGGER_PACKET_COUNT =
                "pdp_watchdog_trigger_packet_count";
 
-       /**
+        /**
         * The number of polls to perform (at {@link #PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS})
         * after hitting {@link #PDP_WATCHDOG_TRIGGER_PACKET_COUNT} before
         * attempting data connection recovery.
         * @hide
         */
-       public static final String PDP_WATCHDOG_ERROR_POLL_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_ERROR_POLL_COUNT =
                "pdp_watchdog_error_poll_count";
 
-       /**
+        /**
         * The number of failed PDP reset attempts before moving to something more
         * drastic: re-registering to the network.
         * @hide
         */
-       public static final String PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT =
                "pdp_watchdog_max_pdp_reset_fail_count";
 
-       /**
+        /**
         * URL to open browser on to allow user to manage a prepay account
         * @hide
         */
-       public static final String SETUP_PREPAID_DATA_SERVICE_URL =
+        @Readable
+        public static final String SETUP_PREPAID_DATA_SERVICE_URL =
                "setup_prepaid_data_service_url";
 
-       /**
+        /**
         * URL to attempt a GET on to see if this is a prepay device
         * @hide
         */
-       public static final String SETUP_PREPAID_DETECTION_TARGET_URL =
+        @Readable
+        public static final String SETUP_PREPAID_DETECTION_TARGET_URL =
                "setup_prepaid_detection_target_url";
 
-       /**
+        /**
         * Host to check for a redirect to after an attempt to GET
         * SETUP_PREPAID_DETECTION_TARGET_URL. (If we redirected there,
         * this is a prepaid device with zero balance.)
         * @hide
         */
-       public static final String SETUP_PREPAID_DETECTION_REDIR_HOST =
+        @Readable
+        public static final String SETUP_PREPAID_DETECTION_REDIR_HOST =
                "setup_prepaid_detection_redir_host";
 
-       /**
+        /**
         * The interval in milliseconds at which to check the number of SMS sent out without asking
         * for use permit, to limit the un-authorized SMS usage.
         *
         * @hide
         */
-       public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
+        @Readable
+        public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
                "sms_outgoing_check_interval_ms";
 
-       /**
+        /**
         * The number of outgoing SMS sent without asking for user permit (of {@link
         * #SMS_OUTGOING_CHECK_INTERVAL_MS}
         *
         * @hide
         */
-       public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
+        @Readable
+        public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
                "sms_outgoing_check_max_count";
 
-       /**
+        /**
         * Used to disable SMS short code confirmation - defaults to true.
         * True indcates we will do the check, etc.  Set to false to disable.
         * @see com.android.internal.telephony.SmsUsageMonitor
         * @hide
         */
-       public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation";
+        @Readable
+        public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation";
 
         /**
          * Used to select which country we use to determine premium sms codes.
@@ -10475,6 +11160,7 @@
          * or com.android.internal.telephony.SMSDispatcher.PREMIUM_RULE_USE_BOTH.
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
 
         /**
@@ -10482,6 +11168,7 @@
          * build config value.
          * @hide
          */
+        @Readable
         public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
 
         /**
@@ -10489,6 +11176,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String TETHER_SUPPORTED = "tether_supported";
 
         /**
@@ -10496,6 +11184,7 @@
          * which defaults to false.
          * @hide
          */
+        @Readable
         public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
 
         /**
@@ -10507,6 +11196,7 @@
          * note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
          * @hide
          */
+        @Readable
         public static final String TETHER_DUN_APN = "tether_dun_apn";
 
         /**
@@ -10517,6 +11207,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled";
 
         /**
@@ -10526,6 +11217,7 @@
          * is interpreted as |false|.
          * @hide
          */
+        @Readable
         public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
                 "tether_enable_legacy_dhcp_server";
 
@@ -10540,6 +11232,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
 
         /**
@@ -10550,62 +11243,71 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String CARRIER_APP_NAMES = "carrier_app_names";
 
-       /**
+        /**
         * USB Mass Storage Enabled
         */
-       public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
+        @Readable
+        public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
 
-       /**
+        /**
         * If this setting is set (to anything), then all references
         * to Gmail on the device must change to Google Mail.
         */
-       public static final String USE_GOOGLE_MAIL = "use_google_mail";
+        @Readable
+        public static final String USE_GOOGLE_MAIL = "use_google_mail";
 
         /**
          * Whether or not switching/creating users is enabled by user.
          * @hide
          */
+        @Readable
         public static final String USER_SWITCHER_ENABLED = "user_switcher_enabled";
 
         /**
          * Webview Data reduction proxy key.
          * @hide
          */
+        @Readable
         public static final String WEBVIEW_DATA_REDUCTION_PROXY_KEY =
                 "webview_data_reduction_proxy_key";
 
-       /**
+        /**
         * Name of the package used as WebView provider (if unset the provider is instead determined
         * by the system).
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String WEBVIEW_PROVIDER = "webview_provider";
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
+        public static final String WEBVIEW_PROVIDER = "webview_provider";
 
-       /**
+        /**
         * Developer setting to enable WebView multiprocess rendering.
         * @hide
         */
-       @SystemApi
-       public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
+        @SystemApi
+        @Readable
+        public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
 
-       /**
+        /**
         * The maximum number of notifications shown in 24 hours when switching networks.
         * @hide
         */
-       public static final String NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT =
+        @Readable
+        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 =
+        @Readable
+        public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
               "network_switch_notification_rate_limit_millis";
 
-       /**
+        /**
         * Whether to automatically switch away from wifi networks that lose Internet access.
         * Only meaningful if config_networkAvoidBadWifi is set to 0, otherwise the system always
         * avoids such networks. Valid values are:
@@ -10616,16 +11318,18 @@
         *
         * @hide
         */
-       public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
+        @Readable
+        public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
 
-       /**
+        /**
         * 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 =
+        @Readable
+        public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
                "network_metered_multipath_preference";
 
         /**
@@ -10634,6 +11338,7 @@
          * from data plan or data limit/warning set by the user.
          * @hide
          */
+        @Readable
         public static final String NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES =
                 "network_default_daily_multipath_quota_bytes";
 
@@ -10641,10 +11346,11 @@
          * Network watchlist last report time.
          * @hide
          */
+        @Readable
         public static final String NETWORK_WATCHLIST_LAST_REPORT_TIME =
                 "network_watchlist_last_report_time";
 
-       /**
+        /**
         * The thresholds of the wifi throughput badging (SD, HD etc.) as a comma-delimited list of
         * colon-delimited key-value pairs. The key is the badging enum value defined in
         * android.net.ScoredNetwork and the value is the minimum sustained network throughput in
@@ -10652,25 +11358,28 @@
         *
         * @hide
         */
-       @SystemApi
-       public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
+        @SystemApi
+        @Readable
+        public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
 
-       /**
+        /**
         * Whether Wifi display is enabled/disabled
         * 0=disabled. 1=enabled.
         * @hide
         */
-       public static final String WIFI_DISPLAY_ON = "wifi_display_on";
+        @Readable
+        public static final String WIFI_DISPLAY_ON = "wifi_display_on";
 
-       /**
+        /**
         * Whether Wifi display certification mode is enabled/disabled
         * 0=disabled. 1=enabled.
         * @hide
         */
-       public static final String WIFI_DISPLAY_CERTIFICATION_ON =
+        @Readable
+        public static final String WIFI_DISPLAY_CERTIFICATION_ON =
                "wifi_display_certification_on";
 
-       /**
+        /**
         * WPS Configuration method used by Wifi display, this setting only
         * takes effect when WIFI_DISPLAY_CERTIFICATION_ON is 1 (enabled).
         *
@@ -10682,10 +11391,11 @@
         * WpsInfo.DISPLAY: use Display
         * @hide
         */
-       public static final String WIFI_DISPLAY_WPS_CONFIG =
+        @Readable
+        public static final String WIFI_DISPLAY_WPS_CONFIG =
            "wifi_display_wps_config";
 
-       /**
+        /**
         * Whether to notify the user of open networks.
         * <p>
         * If not connected and the scan results have an open network, we will
@@ -10697,68 +11407,78 @@
         * @deprecated This feature is no longer controlled by this setting in
         * {@link android.os.Build.VERSION_CODES#O}.
         */
-       @Deprecated
-       public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+        @Deprecated
+        @Readable
+        public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
                "wifi_networks_available_notification_on";
 
-       /**
+        /**
         * {@hide}
         */
-       public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+        @Readable
+        public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
                "wimax_networks_available_notification_on";
 
-       /**
+        /**
         * Delay (in seconds) before repeating the Wi-Fi networks available notification.
         * Connecting to a network will reset the timer.
         * @deprecated This is no longer used or set by the platform.
         */
-       @Deprecated
-       public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
+        @Deprecated
+        @Readable
+        public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
                "wifi_networks_available_repeat_delay";
 
-       /**
+        /**
         * 802.11 country code in ISO 3166 format
         * @hide
         */
-       public static final String WIFI_COUNTRY_CODE = "wifi_country_code";
+        @Readable
+        public static final String WIFI_COUNTRY_CODE = "wifi_country_code";
 
-       /**
+        /**
         * The interval in milliseconds to issue wake up scans when wifi needs
         * to connect. This is necessary to connect to an access point when
         * device is on the move and the screen is off.
         * @hide
         */
-       public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS =
+        @Readable
+        public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS =
                "wifi_framework_scan_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds after which Wi-Fi is considered idle.
         * When idle, it is possible for the device to be switched from Wi-Fi to
         * the mobile data network.
         * @hide
         */
-       public static final String WIFI_IDLE_MS = "wifi_idle_ms";
+        @Readable
+        public static final String WIFI_IDLE_MS = "wifi_idle_ms";
 
-       /**
+        /**
         * When the number of open networks exceeds this number, the
         * least-recently-used excess networks will be removed.
         * @deprecated This is no longer used or set by the platform.
         */
-       @Deprecated
-       public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
+        @Deprecated
+        @Readable
+        public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
 
-       /**
+        /**
         * Whether the Wi-Fi should be on.  Only the Wi-Fi service should touch this.
         */
-       public static final String WIFI_ON = "wifi_on";
+        @Readable
+        public static final String WIFI_ON = "wifi_on";
 
-       /**
+        /**
         * Setting to allow scans to be enabled even wifi is turned off for connectivity.
         * @hide
         * @deprecated To be removed. Use {@link WifiManager#setScanAlwaysAvailable(boolean)} for
         * setting the value and {@link WifiManager#isScanAlwaysAvailable()} for query.
         */
-       public static final String WIFI_SCAN_ALWAYS_AVAILABLE =
+        @Deprecated
+        @Readable
+        public static final String WIFI_SCAN_ALWAYS_AVAILABLE =
                 "wifi_scan_always_enabled";
 
         /**
@@ -10768,6 +11488,8 @@
          * @hide
          * @deprecated To be removed.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_P2P_PENDING_FACTORY_RESET =
                 "wifi_p2p_pending_factory_reset";
 
@@ -10780,6 +11502,8 @@
          * setAutoShutdownEnabled(boolean)} for setting the value and {@link SoftApConfiguration#
          * isAutoShutdownEnabled()} for query.
          */
+        @Deprecated
+        @Readable
         public static final String SOFT_AP_TIMEOUT_ENABLED = "soft_ap_timeout_enabled";
 
         /**
@@ -10792,6 +11516,7 @@
          */
         @Deprecated
         @SystemApi
+        @Readable
         public static final String WIFI_WAKEUP_ENABLED = "wifi_wakeup_enabled";
 
         /**
@@ -10801,6 +11526,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String WIFI_MIGRATION_COMPLETED = "wifi_migration_completed";
 
         /**
@@ -10809,6 +11535,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String NETWORK_SCORING_UI_ENABLED = "network_scoring_ui_enabled";
 
         /**
@@ -10818,6 +11545,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS =
                 "speed_label_cache_eviction_age_millis";
 
@@ -10836,6 +11564,8 @@
          * @hide
          * @deprecated To be removed.
          */
+        @Deprecated
+        @Readable
         public static final String NETWORK_RECOMMENDATIONS_ENABLED =
                 "network_recommendations_enabled";
 
@@ -10849,6 +11579,7 @@
          * Type: string - package name
          * @hide
          */
+        @Readable
         public static final String NETWORK_RECOMMENDATIONS_PACKAGE =
                 "network_recommendations_package";
 
@@ -10860,6 +11591,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
 
         /**
@@ -10869,6 +11601,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS =
                 "recommended_network_evaluator_cache_expiry_ms";
 
@@ -10880,6 +11613,8 @@
          * @deprecated Use {@link WifiManager#setScanThrottleEnabled(boolean)} for setting the value
          * and {@link WifiManager#isScanThrottleEnabled()} for query.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_SCAN_THROTTLE_ENABLED = "wifi_scan_throttle_enabled";
 
         /**
@@ -10887,24 +11622,28 @@
         * connectivity.
         * @hide
         */
+        @Readable
         public static final String BLE_SCAN_ALWAYS_AVAILABLE = "ble_scan_always_enabled";
 
         /**
          * The length in milliseconds of a BLE scan window in a low-power scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_POWER_WINDOW_MS = "ble_scan_low_power_window_ms";
 
         /**
          * The length in milliseconds of a BLE scan window in a balanced scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BALANCED_WINDOW_MS = "ble_scan_balanced_window_ms";
 
         /**
          * The length in milliseconds of a BLE scan window in a low-latency scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_LATENCY_WINDOW_MS =
                 "ble_scan_low_latency_window_ms";
 
@@ -10912,6 +11651,7 @@
          * The length in milliseconds of a BLE scan interval in a low-power scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_POWER_INTERVAL_MS =
                 "ble_scan_low_power_interval_ms";
 
@@ -10919,6 +11659,7 @@
          * The length in milliseconds of a BLE scan interval in a balanced scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BALANCED_INTERVAL_MS =
                 "ble_scan_balanced_interval_ms";
 
@@ -10926,6 +11667,7 @@
          * The length in milliseconds of a BLE scan interval in a low-latency scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_LATENCY_INTERVAL_MS =
                 "ble_scan_low_latency_interval_ms";
 
@@ -10933,26 +11675,30 @@
          * The mode that BLE scanning clients will be moved to when in the background.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BACKGROUND_MODE = "ble_scan_background_mode";
 
-       /**
+        /**
         * The interval in milliseconds to scan as used by the wifi supplicant
         * @hide
         */
-       public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS =
+        @Readable
+        public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS =
                "wifi_supplicant_scan_interval_ms";
 
         /**
          * whether frameworks handles wifi auto-join
          * @hide
          */
-       public static final String WIFI_ENHANCED_AUTO_JOIN =
+        @Readable
+        public static final String WIFI_ENHANCED_AUTO_JOIN =
                 "wifi_enhanced_auto_join";
 
         /**
          * whether settings show RSSI
          * @hide
          */
+        @Readable
         public static final String WIFI_NETWORK_SHOW_RSSI =
                 "wifi_network_show_rssi";
 
@@ -10960,31 +11706,36 @@
         * The interval in milliseconds to scan at supplicant when p2p is connected
         * @hide
         */
-       public static final String WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS =
+        @Readable
+        public static final String WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS =
                "wifi_scan_interval_p2p_connected_ms";
 
-       /**
+        /**
         * Whether the Wi-Fi watchdog is enabled.
         */
-       public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
+        @Readable
+        public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
 
-       /**
+        /**
         * Setting to turn off poor network avoidance on Wi-Fi. Feature is enabled by default and
         * the setting needs to be set to 0 to disable it.
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
+        public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
                "wifi_watchdog_poor_network_test_enabled";
 
-       /**
+        /**
         * Setting to enable verbose logging in Wi-Fi; disabled by default, and setting to 1
         * will enable it. In the future, additional values may be supported.
         * @hide
         * @deprecated Use {@link WifiManager#setVerboseLoggingEnabled(boolean)} for setting the
         * value and {@link WifiManager#isVerboseLoggingEnabled()} for query.
         */
-       public static final String WIFI_VERBOSE_LOGGING_ENABLED =
+        @Deprecated
+        @Readable
+        public static final String WIFI_VERBOSE_LOGGING_ENABLED =
                "wifi_verbose_logging_enabled";
 
         /**
@@ -10994,6 +11745,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED =
                 "wifi_connected_mac_randomization_enabled";
 
@@ -11010,24 +11762,28 @@
          * @hide
          * @deprecated This is no longer used or set by the platform.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_SCORE_PARAMS =
                 "wifi_score_params";
 
-       /**
+        /**
         * The maximum number of times we will retry a connection to an access
         * point for which we have failed in acquiring an IP address from DHCP.
         * A value of N means that we will make N+1 connection attempts in all.
         */
-       public static final String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
+        @Readable
+        public static final String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
 
-       /**
+        /**
         * Maximum amount of time in milliseconds to hold a wakelock while waiting for mobile
         * data connectivity to be established after a disconnect from Wi-Fi.
         */
-       public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS =
+        @Readable
+        public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS =
            "wifi_mobile_data_transition_wakelock_timeout_ms";
 
-       /**
+        /**
         * This setting controls whether WiFi configurations created by a Device Owner app
         * should be locked down (that is, be editable or removable only by the Device Owner App,
         * not even by Settings app).
@@ -11035,10 +11791,11 @@
         * are locked down. Value of zero means they are not. Default value in the absence of
         * actual value to this setting is 0.
         */
-       public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
+        @Readable
+        public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
                "wifi_device_owner_configs_lockdown";
 
-       /**
+        /**
         * The operational wifi frequency band
         * Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
         * {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or
@@ -11046,18 +11803,21 @@
         *
         * @hide
         */
-       public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
+        @Readable
+        public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
 
-       /**
+        /**
         * The Wi-Fi peer-to-peer device name
         * @hide
         * @deprecated Use {@link WifiP2pManager#setDeviceName(WifiP2pManager.Channel, String,
         * WifiP2pManager.ActionListener)} for setting the value and
         * {@link android.net.wifi.p2p.WifiP2pDevice#deviceName} for query.
         */
-       public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
+        @Deprecated
+        @Readable
+        public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
 
-       /**
+        /**
         * Timeout for ephemeral networks when all known BSSIDs go out of range. We will disconnect
         * from an ephemeral network if there is no BSSID for that network with a non-null score that
         * has been seen in this time period.
@@ -11066,53 +11826,60 @@
         * for a non-null score from the currently connected or target BSSID.
         * @hide
         */
-       public static final String WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS =
+        @Readable
+        public static final String WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS =
                "wifi_ephemeral_out_of_range_timeout_ms";
 
-       /**
+        /**
         * The number of milliseconds to delay when checking for data stalls during
         * non-aggressive detection. (screen is turned off.)
         * @hide
         */
-       public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
+        @Readable
+        public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
                "data_stall_alarm_non_aggressive_delay_in_ms";
 
-       /**
+        /**
         * The number of milliseconds to delay when checking for data stalls during
         * aggressive detection. (screen on or suspected data stall)
         * @hide
         */
-       public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
+        @Readable
+        public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
                "data_stall_alarm_aggressive_delay_in_ms";
 
-       /**
+        /**
         * The number of milliseconds to allow the provisioning apn to remain active
         * @hide
         */
-       public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
+        @Readable
+        public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
                "provisioning_apn_alarm_delay_in_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check gprs registration
         * after the first registration mismatch of gprs and voice service,
         * to detect possible data network registration problems.
         *
         * @hide
         */
-       public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
+        @Readable
+        public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
                "gprs_register_check_period_ms";
 
-       /**
+        /**
         * Nonzero causes Log.wtf() to crash.
         * @hide
         */
-       public static final String WTF_IS_FATAL = "wtf_is_fatal";
+        @Readable
+        public static final String WTF_IS_FATAL = "wtf_is_fatal";
 
-       /**
+        /**
         * Ringer mode. This is used internally, changing this value will not
         * change the ringer mode. See AudioManager.
         */
-       public static final String MODE_RINGER = "mode_ringer";
+        @Readable
+        public static final String MODE_RINGER = "mode_ringer";
 
         /**
          * Overlay display devices setting.
@@ -11153,6 +11920,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
 
         /**
@@ -11161,10 +11929,12 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 BATTERY_DISCHARGE_DURATION_THRESHOLD = "battery_discharge_duration_threshold";
 
         /** @hide */
+        @Readable
         public static final String BATTERY_DISCHARGE_THRESHOLD = "battery_discharge_threshold";
 
         /**
@@ -11176,6 +11946,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SEND_ACTION_APP_ERROR = "send_action_app_error";
 
         /**
@@ -11183,6 +11954,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds";
 
         /**
@@ -11191,6 +11963,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_MAX_FILES = "dropbox_max_files";
 
         /**
@@ -11199,6 +11972,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb";
 
         /**
@@ -11207,6 +11981,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent";
 
         /**
@@ -11215,6 +11990,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_RESERVE_PERCENT = "dropbox_reserve_percent";
 
         /**
@@ -11222,6 +11998,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_TAG_PREFIX = "dropbox:";
 
         /**
@@ -11232,6 +12009,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ERROR_LOGCAT_PREFIX = "logcat_for_";
 
         /**
@@ -11245,6 +12023,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAX_ERROR_BYTES_PREFIX = "max_error_bytes_for_";
 
         /**
@@ -11253,6 +12032,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SYS_FREE_STORAGE_LOG_INTERVAL = "sys_free_storage_log_interval";
 
         /**
@@ -11262,6 +12042,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 DISK_FREE_CHANGE_REPORTING_THRESHOLD = "disk_free_change_reporting_threshold";
 
@@ -11274,6 +12055,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage";
 
@@ -11285,6 +12067,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_THRESHOLD_MAX_BYTES = "sys_storage_threshold_max_bytes";
 
@@ -11295,6 +12078,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_FULL_THRESHOLD_BYTES = "sys_storage_full_threshold_bytes";
 
@@ -11304,6 +12088,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_CACHE_PERCENTAGE = "sys_storage_cache_percentage";
 
@@ -11313,6 +12098,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_CACHE_MAX_BYTES = "sys_storage_cache_max_bytes";
 
@@ -11322,6 +12108,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYNC_MAX_RETRY_DELAY_IN_SECONDS = "sync_max_retry_delay_in_seconds";
 
@@ -11331,6 +12118,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay";
 
 
@@ -11340,7 +12128,7 @@
          *
          * @hide
          */
-
+        @Readable
         public static final String CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS =
                 "connectivity_sampling_interval_in_seconds";
 
@@ -11350,6 +12138,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PAC_CHANGE_DELAY = "pac_change_delay";
 
         /**
@@ -11382,6 +12171,7 @@
          * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
 
         /**
@@ -11392,6 +12182,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String
                 CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
 
@@ -11402,6 +12193,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_SERVER = "captive_portal_server";
 
         /**
@@ -11410,6 +12202,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
 
         /**
@@ -11418,6 +12211,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
 
         /**
@@ -11426,6 +12220,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
 
         /**
@@ -11434,6 +12229,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
                 "captive_portal_other_fallback_urls";
 
@@ -11443,6 +12239,7 @@
          * by "@@,@@".
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
                 "captive_portal_fallback_probe_specs";
 
@@ -11453,6 +12250,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
 
         /**
@@ -11461,6 +12259,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
 
         /**
@@ -11468,6 +12267,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATA_STALL_RECOVERY_ON_BAD_NETWORK =
                 "data_stall_recovery_on_bad_network";
 
@@ -11476,6 +12276,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS =
                 "min_duration_between_recovery_steps";
         /**
@@ -11483,6 +12284,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String NSD_ON = "nsd_on";
 
         /**
@@ -11490,6 +12292,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SET_INSTALL_LOCATION = "set_install_location";
 
         /**
@@ -11499,6 +12302,7 @@
          * 2 = sdcard
          * @hide
          */
+        @Readable
         public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
 
         /**
@@ -11507,6 +12311,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 INET_CONDITION_DEBOUNCE_UP_DELAY = "inet_condition_debounce_up_delay";
 
@@ -11516,10 +12321,12 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 INET_CONDITION_DEBOUNCE_DOWN_DELAY = "inet_condition_debounce_down_delay";
 
         /** {@hide} */
+        @Readable
         public static final String
                 READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT = "read_external_storage_enforced_default";
 
@@ -11527,6 +12334,7 @@
          * Host name and port for global http proxy. Uses ':' seperator for
          * between host and port.
          */
+        @Readable
         public static final String HTTP_PROXY = "http_proxy";
 
         /**
@@ -11534,6 +12342,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host";
 
         /**
@@ -11541,6 +12350,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port";
 
         /**
@@ -11552,6 +12362,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 GLOBAL_HTTP_PROXY_EXCLUSION_LIST = "global_http_proxy_exclusion_list";
 
@@ -11559,6 +12370,7 @@
          * The location PAC File for the proxy.
          * @hide
          */
+        @Readable
         public static final String
                 GLOBAL_HTTP_PROXY_PAC = "global_proxy_pac_url";
 
@@ -11568,6 +12380,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SET_GLOBAL_HTTP_PROXY = "set_global_http_proxy";
 
         /**
@@ -11575,6 +12388,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEFAULT_DNS_SERVER = "default_dns_server";
 
         /**
@@ -11587,11 +12401,13 @@
          *
          * @hide
          */
+        @Readable
         public static final String PRIVATE_DNS_MODE = "private_dns_mode";
 
         /**
          * @hide
          */
+        @Readable
         public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
 
         /**
@@ -11603,46 +12419,60 @@
           *
           * {@hide}
           */
+        @Readable
         public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
 
 
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_BTSNOOP_DEFAULT_MODE = "bluetooth_btsnoop_default_mode";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX = "bluetooth_a2dp_sink_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_";
         /** {@hide} */
+        @Readable
         public static final String BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX =
                 "bluetooth_a2dp_supports_optional_codecs_";
         /** {@hide} */
+        @Readable
         public static final String BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX =
                 "bluetooth_a2dp_optional_codecs_enabled_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_MAP_CLIENT_PRIORITY_PREFIX = "bluetooth_map_client_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_PBAP_CLIENT_PRIORITY_PREFIX = "bluetooth_pbap_client_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_SAP_PRIORITY_PREFIX = "bluetooth_sap_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_HEARING_AID_PRIORITY_PREFIX = "bluetooth_hearing_aid_priority_";
 
@@ -11651,6 +12481,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 ENABLE_RADIO_BUG_DETECTION = "enable_radio_bug_detection";
 
@@ -11659,6 +12490,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 RADIO_BUG_WAKELOCK_TIMEOUT_COUNT_THRESHOLD =
                 "radio_bug_wakelock_timeout_count_threshold";
@@ -11668,6 +12500,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 RADIO_BUG_SYSTEM_ERROR_COUNT_THRESHOLD =
                 "radio_bug_system_error_count_threshold";
@@ -11714,6 +12547,7 @@
          * @hide
          * @see com.android.server.am.ActivityManagerConstants
          */
+        @Readable
         public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
 
         /**
@@ -11722,6 +12556,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String ACTIVITY_STARTS_LOGGING_ENABLED
                 = "activity_starts_logging_enabled";
 
@@ -11731,6 +12566,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED =
                 "foreground_service_starts_logging_enabled";
 
@@ -11738,6 +12574,7 @@
          * @hide
          * @see com.android.server.appbinding.AppBindingConstants
          */
+        @Readable
         public static final String APP_BINDING_CONSTANTS = "app_binding_constants";
 
         /**
@@ -11760,6 +12597,7 @@
          * @see com.android.server.AppOpsService.Constants
          */
         @TestApi
+        @Readable
         public static final String APP_OPS_CONSTANTS = "app_ops_constants";
 
         /**
@@ -11795,6 +12633,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
 
         /**
@@ -11812,6 +12651,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS =
                 "battery_saver_device_specific_constants";
 
@@ -11841,6 +12681,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String BATTERY_TIP_CONSTANTS = "battery_tip_constants";
 
         /**
@@ -11866,6 +12707,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String ANOMALY_DETECTION_CONSTANTS = "anomaly_detection_constants";
 
         /**
@@ -11873,6 +12715,7 @@
          * current version is 1.
          * @hide
          */
+        @Readable
         public static final String ANOMALY_CONFIG_VERSION = "anomaly_config_version";
 
         /**
@@ -11880,6 +12723,7 @@
          * {@link android.app.StatsManager}.
          * @hide
          */
+        @Readable
         public static final String ANOMALY_CONFIG = "anomaly_config";
 
         /**
@@ -11899,6 +12743,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_DISPLAY_CONSTANTS = "always_on_display_constants";
 
         /**
@@ -11909,6 +12754,7 @@
         * Any other value defaults to enabled.
         * @hide
         */
+        @Readable
         public static final String SYS_UIDCPUPOWER = "sys_uidcpupower";
 
         /**
@@ -11920,6 +12766,7 @@
         * Any other value defaults to disabled.
         * @hide
         */
+        @Readable
         public static final String SYS_TRACED = "sys_traced";
 
         /**
@@ -11928,6 +12775,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FPS_DEVISOR = "fps_divisor";
 
         /**
@@ -11937,6 +12785,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DISPLAY_PANEL_LPM = "display_panel_lpm";
 
         /**
@@ -11951,6 +12800,7 @@
          * Need to reboot the device for this setting to take effect.
          * @hide
          */
+        @Readable
         public static final String APP_TIME_LIMIT_USAGE_SOURCE = "app_time_limit_usage_source";
 
         /**
@@ -11958,6 +12808,7 @@
          * 0 = disable, 1 = enable.
          * @hide
          */
+        @Readable
         public static final String ART_VERIFIER_VERIFY_DEBUGGABLE =
                 "art_verifier_verify_debuggable";
 
@@ -11978,6 +12829,7 @@
          * @hide
          * @see com.android.server.power.PowerManagerConstants
          */
+        @Readable
         public static final String POWER_MANAGER_CONSTANTS = "power_manager_constants";
 
         /**
@@ -12003,6 +12855,7 @@
          * @hide
          * @see com.android.server.pm.ShortcutService.ConfigConstants
          */
+        @Readable
         public static final String SHORTCUT_MANAGER_CONSTANTS = "shortcut_manager_constants";
 
         /**
@@ -12020,6 +12873,7 @@
          * @hide
          * see also com.android.server.devicepolicy.DevicePolicyConstants
          */
+        @Readable
         public static final String DEVICE_POLICY_CONSTANTS = "device_policy_constants";
 
         /**
@@ -12056,6 +12910,7 @@
          * @hide
          * see also android.view.textclassifier.TextClassificationConstants
          */
+        @Readable
         public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";
 
         /**
@@ -12080,6 +12935,7 @@
          * @hide
          * see also com.android.internal.os.BatteryStatsImpl.Constants
          */
+        @Readable
         public static final String BATTERY_STATS_CONSTANTS = "battery_stats_constants";
 
         /**
@@ -12090,6 +12946,7 @@
          * @hide
          * @see com.android.server.content.SyncManagerConstants
          */
+        @Readable
         public static final String SYNC_MANAGER_CONSTANTS = "sync_manager_constants";
 
         /**
@@ -12109,6 +12966,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_FG_CONSTANTS = "bcast_fg_constants";
 
         /**
@@ -12119,6 +12977,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_BG_CONSTANTS = "bcast_bg_constants";
 
         /**
@@ -12129,6 +12988,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_OFFLOAD_CONSTANTS = "bcast_offload_constants";
 
         /**
@@ -12141,6 +13001,7 @@
          * @see #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED
          */
         @SystemApi
+        @Readable
         public static final String APP_STANDBY_ENABLED = "app_standby_enabled";
 
         /**
@@ -12151,6 +13012,7 @@
          * @hide
          * @see #APP_STANDBY_ENABLED
          */
+        @Readable
         public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
                 "adaptive_battery_management_enabled";
 
@@ -12162,6 +13024,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_RESTRICTED_BUCKET = "enable_restricted_bucket";
 
         /**
@@ -12179,6 +13042,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APP_AUTO_RESTRICTION_ENABLED =
                 "app_auto_restriction_enabled";
 
@@ -12188,6 +13052,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String FORCED_APP_STANDBY_ENABLED = "forced_app_standby_enabled";
 
         /**
@@ -12196,6 +13061,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED
                 = "forced_app_standby_for_small_battery_enabled";
 
@@ -12205,6 +13071,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String USER_ABSENT_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED
                 = "user_absent_radios_off_for_small_battery_enabled";
 
@@ -12214,6 +13081,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String USER_ABSENT_TOUCH_OFF_FOR_SMALL_BATTERY_ENABLED
                 = "user_absent_touch_off_for_small_battery_enabled";
 
@@ -12223,6 +13091,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String WIFI_ON_WHEN_PROXY_DISCONNECTED
                 = "wifi_on_when_proxy_disconnected";
 
@@ -12241,6 +13110,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String TIME_ONLY_MODE_CONSTANTS
                 = "time_only_mode_constants";
 
@@ -12251,6 +13121,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String UNGAZE_SLEEP_ENABLED = "ungaze_sleep_enabled";
 
         /**
@@ -12259,6 +13130,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String NETWORK_WATCHLIST_ENABLED = "network_watchlist_enabled";
 
         /**
@@ -12267,6 +13139,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED =
                 "show_hidden_icon_apps_enabled";
 
@@ -12276,6 +13149,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED =
                 "show_new_app_installed_notification_enabled";
 
@@ -12289,6 +13163,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KEEP_PROFILE_IN_BACKGROUND = "keep_profile_in_background";
 
         /**
@@ -12310,6 +13185,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADB_ALLOWED_CONNECTION_TIME =
                 "adb_allowed_connection_time";
 
@@ -12317,12 +13193,14 @@
          * Scaling factor for normal window animations. Setting to 0 will
          * disable window animations.
          */
+        @Readable
         public static final String WINDOW_ANIMATION_SCALE = "window_animation_scale";
 
         /**
          * Scaling factor for activity transition animations. Setting to 0 will
          * disable window animations.
          */
+        @Readable
         public static final String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
 
         /**
@@ -12330,6 +13208,7 @@
          * start delay and duration of all such animations. Setting to 0 will
          * cause animations to end immediately. The default value is 1.
          */
+        @Readable
         public static final String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
 
         /**
@@ -12338,6 +13217,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FANCY_IME_ANIMATIONS = "fancy_ime_animations";
 
         /**
@@ -12346,6 +13226,7 @@
          * TODO: remove this settings before code freeze (bug/1907571)
          * @hide
          */
+        @Readable
         public static final String COMPATIBILITY_MODE = "compatibility_mode";
 
         /**
@@ -12355,6 +13236,7 @@
          *                 2 = Vibrate
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_TONE = "emergency_tone";
 
         /**
@@ -12363,6 +13245,7 @@
          * boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String CALL_AUTO_RETRY = "call_auto_retry";
 
         /**
@@ -12370,6 +13253,7 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_AFFORDANCE_NEEDED = "emergency_affordance_needed";
 
         /**
@@ -12379,6 +13263,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS =
                 "enable_automatic_system_server_heap_dumps";
 
@@ -12387,18 +13272,21 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String PREFERRED_NETWORK_MODE =
                 "preferred_network_mode";
 
         /**
          * Name of an application package to be debugged.
          */
+        @Readable
         public static final String DEBUG_APP = "debug_app";
 
         /**
          * If 1, when launching DEBUG_APP it will wait for the debugger before
          * starting user code.  If 0, it will run normally.
          */
+        @Readable
         public static final String WAIT_FOR_DEBUGGER = "wait_for_debugger";
 
         /**
@@ -12407,12 +13295,14 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String ENABLE_GPU_DEBUG_LAYERS = "enable_gpu_debug_layers";
 
         /**
          * App allowed to load GPU debug layers
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_APP = "gpu_debug_app";
 
         /**
@@ -12420,6 +13310,7 @@
          * to dumpable apps that opt-in.
          * @hide
          */
+        @Readable
         public static final String ANGLE_DEBUG_PACKAGE = "angle_debug_package";
 
         /**
@@ -12427,12 +13318,14 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_ALL_ANGLE = "angle_gl_driver_all_angle";
 
         /**
          * List of PKGs that have an OpenGL driver selected
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_SELECTION_PKGS =
                 "angle_gl_driver_selection_pkgs";
 
@@ -12440,6 +13333,7 @@
          * List of selected OpenGL drivers, corresponding to the PKGs in GLOBAL_SETTINGS_DRIVER_PKGS
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_SELECTION_VALUES =
                 "angle_gl_driver_selection_values";
 
@@ -12447,6 +13341,7 @@
          * List of package names that should check ANGLE rules
          * @hide
          */
+        @Readable
         public static final String ANGLE_ALLOWLIST = "angle_allowlist";
 
         /**
@@ -12456,6 +13351,7 @@
          * e.g. feature1:feature2:feature3,feature1:feature3:feature5
          * @hide
          */
+        @Readable
         public static final String ANGLE_EGL_FEATURES = "angle_egl_features";
 
         /**
@@ -12463,6 +13359,7 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String SHOW_ANGLE_IN_USE_DIALOG_BOX = "show_angle_in_use_dialog_box";
 
         /**
@@ -12473,6 +13370,7 @@
          * 3 = All Apps use system graphics driver
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_ALL_APPS = "updatable_driver_all_apps";
 
         /**
@@ -12480,6 +13378,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS =
                 "updatable_driver_production_opt_in_apps";
 
@@ -12488,6 +13387,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS =
                 "updatable_driver_prerelease_opt_in_apps";
 
@@ -12496,6 +13396,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS =
                 "updatable_driver_production_opt_out_apps";
 
@@ -12503,6 +13404,7 @@
          * Apps on the denylist that are forbidden to use updatable production driver.
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLIST =
                 "updatable_driver_production_denylist";
 
@@ -12511,6 +13413,7 @@
          * updatable production driver.
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLISTS =
                 "updatable_driver_production_denylists";
 
@@ -12520,6 +13423,7 @@
          * i.e. <apk1>,<apk2>,...,<apkN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST =
                 "updatable_driver_production_allowlist";
 
@@ -12529,6 +13433,7 @@
          * i.e. <lib1>:<lib2>:...:<libN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES =
                 "updatable_driver_sphal_libraries";
 
@@ -12537,6 +13442,7 @@
          * i.e. <layer1>:<layer2>:...:<layerN>
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYERS = "gpu_debug_layers";
 
         /**
@@ -12544,12 +13450,14 @@
          * i.e. <layer1>:<layer2>:...:<layerN>
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYERS_GLES = "gpu_debug_layers_gles";
 
         /**
          * Addition app for GPU layer discovery
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYER_APP = "gpu_debug_layer_app";
 
         /**
@@ -12559,6 +13467,7 @@
          * {@link android.os.Build.VERSION_CODES#N_MR1}.
          */
         @Deprecated
+        @Readable
         public static final String SHOW_PROCESSES = "show_processes";
 
         /**
@@ -12566,6 +13475,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOW_POWER_MODE = "low_power";
 
         /**
@@ -12574,6 +13484,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
 
         /**
@@ -12583,6 +13494,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL =
                 "low_power_sticky_auto_disable_level";
 
@@ -12592,6 +13504,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED =
                 "low_power_sticky_auto_disable_enabled";
 
@@ -12605,6 +13518,7 @@
          * @see android.os.PowerManager#getPowerSaveModeTrigger()
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
 
         /**
@@ -12615,6 +13529,7 @@
          *  @hide
          */
         @TestApi
+        @Readable
         public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
 
         /**
@@ -12625,6 +13540,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD =
                 "dynamic_power_savings_disable_threshold";
 
@@ -12635,6 +13551,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
 
         /**
@@ -12646,6 +13563,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String TIME_REMAINING_ESTIMATE_MILLIS =
                 "time_remaining_estimate_millis";
 
@@ -12659,6 +13577,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String TIME_REMAINING_ESTIMATE_BASED_ON_USAGE =
                 "time_remaining_estimate_based_on_usage";
 
@@ -12671,6 +13590,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String AVERAGE_TIME_TO_DISCHARGE = "average_time_to_discharge";
 
         /**
@@ -12682,6 +13602,7 @@
          * @deprecated No longer needed due to {@link PowerManager#getBatteryDischargePrediction}.
          */
         @Deprecated
+        @Readable
         public static final String BATTERY_ESTIMATES_LAST_UPDATE_TIME =
                 "battery_estimates_last_update_time";
 
@@ -12691,12 +13612,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL_MAX = "low_power_trigger_level_max";
 
         /**
          * See com.android.settingslib.fuelgauge.BatterySaverUtils.
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_SUGGESTION_PARAMS =
                 "low_power_mode_suggestion_params";
 
@@ -12705,6 +13628,7 @@
          * processes as soon as they are no longer needed.  If 0, the normal
          * extended lifetime is used.
          */
+        @Readable
         public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
 
         /**
@@ -12714,6 +13638,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
 
         /**
@@ -12722,6 +13647,7 @@
          *      1 = enabled
          * @hide
          */
+        @Readable
         public static final String DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled";
 
         /**
@@ -12781,6 +13707,7 @@
          * ENCODED_SURROUND_OUTPUT_MANUAL
          * @hide
          */
+        @Readable
         public static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output";
 
         /**
@@ -12792,6 +13719,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS =
                 "encoded_surround_output_enabled_formats";
 
@@ -12799,36 +13727,42 @@
          * Persisted safe headphone volume management state by AudioService
          * @hide
          */
+        @Readable
         public static final String AUDIO_SAFE_VOLUME_STATE = "audio_safe_volume_state";
 
         /**
          * URL for tzinfo (time zone) updates
          * @hide
          */
+        @Readable
         public static final String TZINFO_UPDATE_CONTENT_URL = "tzinfo_content_url";
 
         /**
          * URL for tzinfo (time zone) update metadata
          * @hide
          */
+        @Readable
         public static final String TZINFO_UPDATE_METADATA_URL = "tzinfo_metadata_url";
 
         /**
          * URL for selinux (mandatory access control) updates
          * @hide
          */
+        @Readable
         public static final String SELINUX_UPDATE_CONTENT_URL = "selinux_content_url";
 
         /**
          * URL for selinux (mandatory access control) update metadata
          * @hide
          */
+        @Readable
         public static final String SELINUX_UPDATE_METADATA_URL = "selinux_metadata_url";
 
         /**
          * URL for sms short code updates
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODES_UPDATE_CONTENT_URL =
                 "sms_short_codes_content_url";
 
@@ -12836,6 +13770,7 @@
          * URL for sms short code update metadata
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODES_UPDATE_METADATA_URL =
                 "sms_short_codes_metadata_url";
 
@@ -12843,30 +13778,35 @@
          * URL for apn_db updates
          * @hide
          */
+        @Readable
         public static final String APN_DB_UPDATE_CONTENT_URL = "apn_db_content_url";
 
         /**
          * URL for apn_db update metadata
          * @hide
          */
+        @Readable
         public static final String APN_DB_UPDATE_METADATA_URL = "apn_db_metadata_url";
 
         /**
          * URL for cert pinlist updates
          * @hide
          */
+        @Readable
         public static final String CERT_PIN_UPDATE_CONTENT_URL = "cert_pin_content_url";
 
         /**
          * URL for cert pinlist updates
          * @hide
          */
+        @Readable
         public static final String CERT_PIN_UPDATE_METADATA_URL = "cert_pin_metadata_url";
 
         /**
          * URL for intent firewall updates
          * @hide
          */
+        @Readable
         public static final String INTENT_FIREWALL_UPDATE_CONTENT_URL =
                 "intent_firewall_content_url";
 
@@ -12874,6 +13814,7 @@
          * URL for intent firewall update metadata
          * @hide
          */
+        @Readable
         public static final String INTENT_FIREWALL_UPDATE_METADATA_URL =
                 "intent_firewall_metadata_url";
 
@@ -12881,18 +13822,21 @@
          * URL for lang id model updates
          * @hide
          */
+        @Readable
         public static final String LANG_ID_UPDATE_CONTENT_URL = "lang_id_content_url";
 
         /**
          * URL for lang id model update metadata
          * @hide
          */
+        @Readable
         public static final String LANG_ID_UPDATE_METADATA_URL = "lang_id_metadata_url";
 
         /**
          * URL for smart selection model updates
          * @hide
          */
+        @Readable
         public static final String SMART_SELECTION_UPDATE_CONTENT_URL =
                 "smart_selection_content_url";
 
@@ -12900,6 +13844,7 @@
          * URL for smart selection model update metadata
          * @hide
          */
+        @Readable
         public static final String SMART_SELECTION_UPDATE_METADATA_URL =
                 "smart_selection_metadata_url";
 
@@ -12907,6 +13852,7 @@
          * URL for conversation actions model updates
          * @hide
          */
+        @Readable
         public static final String CONVERSATION_ACTIONS_UPDATE_CONTENT_URL =
                 "conversation_actions_content_url";
 
@@ -12914,6 +13860,7 @@
          * URL for conversation actions model update metadata
          * @hide
          */
+        @Readable
         public static final String CONVERSATION_ACTIONS_UPDATE_METADATA_URL =
                 "conversation_actions_metadata_url";
 
@@ -12921,12 +13868,14 @@
          * SELinux enforcement status. If 0, permissive; if 1, enforcing.
          * @hide
          */
+        @Readable
         public static final String SELINUX_STATUS = "selinux_status";
 
         /**
          * Developer setting to force RTL layout.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_RTL = "debug.force_rtl";
 
         /**
@@ -12937,6 +13886,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout";
 
         /**
@@ -12946,6 +13896,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String WIFI_BOUNCE_DELAY_OVERRIDE_MS = "wifi_bounce_delay_override_ms";
 
         /**
@@ -12955,6 +13906,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String POLICY_CONTROL = "policy_control";
 
         /**
@@ -12962,6 +13914,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMULATE_DISPLAY_CUTOUT = "emulate_display_cutout";
 
         /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_OFF = 0;
@@ -12972,6 +13925,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKED_SLICES = "blocked_slices";
 
         /**
@@ -12981,6 +13935,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ZEN_MODE = "zen_mode";
 
         /** @hide */
@@ -13020,6 +13975,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ZEN_MODE_RINGER_LEVEL = "zen_mode_ringer_level";
 
         /**
@@ -13028,6 +13984,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ZEN_MODE_CONFIG_ETAG = "zen_mode_config_etag";
 
         /**
@@ -13057,6 +14014,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String HEADS_UP_NOTIFICATIONS_ENABLED =
                 "heads_up_notifications_enabled";
 
@@ -13070,6 +14028,7 @@
         /**
          * The name of the device
          */
+        @Readable
         public static final String DEVICE_NAME = "device_name";
 
         /**
@@ -13078,6 +14037,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String NETWORK_SCORING_PROVISIONED = "network_scoring_provisioned";
 
         /**
@@ -13089,6 +14049,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
 
         /**
@@ -13102,6 +14063,7 @@
          * {@link android.provider.Telephony.SimInfo#COLUMN_ENHANCED_4G_MODE_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String ENHANCED_4G_MODE_ENABLED =
                 Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
 
@@ -13114,6 +14076,7 @@
          * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_VT_IMS_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String VT_IMS_ENABLED = Telephony.SimInfo.COLUMN_VT_IMS_ENABLED;
 
         /**
@@ -13126,6 +14089,7 @@
          * {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ENABLED = Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED;
 
         /**
@@ -13137,6 +14101,7 @@
          * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_MODE} instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_MODE = Telephony.SimInfo.COLUMN_WFC_IMS_MODE;
 
         /**
@@ -13149,6 +14114,7 @@
          * instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ROAMING_MODE =
                 Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
 
@@ -13162,6 +14128,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ROAMING_ENABLED =
                 Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
 
@@ -13172,6 +14139,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String LTE_SERVICE_FORCED = "lte_service_forced";
 
 
@@ -13181,6 +14149,7 @@
          * See WindowManagerPolicy.WindowManagerFuncs
          * @hide
          */
+        @Readable
         public static final String LID_BEHAVIOR = "lid_behavior";
 
         /**
@@ -13189,6 +14158,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String EPHEMERAL_COOKIE_MAX_SIZE_BYTES =
                 "ephemeral_cookie_max_size_bytes";
 
@@ -13200,6 +14170,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature";
 
         /**
@@ -13210,6 +14181,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String INSTANT_APP_DEXOPT_ENABLED = "instant_app_dexopt_enabled";
 
         /**
@@ -13218,6 +14190,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
                 "installed_instant_app_min_cache_period";
 
@@ -13227,6 +14200,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
                 "installed_instant_app_max_cache_period";
 
@@ -13236,6 +14210,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
                 "uninstalled_instant_app_min_cache_period";
 
@@ -13245,6 +14220,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
                 "uninstalled_instant_app_max_cache_period";
 
@@ -13254,6 +14230,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
                 "unused_static_shared_lib_min_cache_period";
 
@@ -13263,6 +14240,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED =
                 "allow_user_switching_when_system_user_locked";
 
@@ -13271,6 +14249,7 @@
          * <p>
          * Type: int
          */
+        @Readable
         public static final String BOOT_COUNT = "boot_count";
 
         /**
@@ -13281,6 +14260,7 @@
          * before the user restrictions are loaded.
          * @hide
          */
+        @Readable
         public static final String SAFE_BOOT_DISALLOWED = "safe_boot_disallowed";
 
         /**
@@ -13292,6 +14272,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEVICE_DEMO_MODE = "device_demo_mode";
 
         /**
@@ -13301,6 +14282,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String NETWORK_ACCESS_TIMEOUT_MS = "network_access_timeout_ms";
 
         /**
@@ -13311,6 +14293,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATABASE_DOWNGRADE_REASON = "database_downgrade_reason";
 
         /**
@@ -13321,6 +14304,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATABASE_CREATION_BUILDID = "database_creation_buildid";
 
         /**
@@ -13329,6 +14313,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONTACTS_DATABASE_WAL_ENABLED = "contacts_database_wal_enabled";
 
         /**
@@ -13336,6 +14321,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED =
                 "location_settings_link_to_permissions_enabled";
 
@@ -13346,6 +14332,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
                 "euicc_removing_invisible_profiles_timeout_millis";
 
@@ -13355,6 +14342,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EUICC_FACTORY_RESET_TIMEOUT_MILLIS =
                 "euicc_factory_reset_timeout_millis";
 
@@ -13364,6 +14352,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String STORAGE_SETTINGS_CLOBBER_THRESHOLD =
                 "storage_settings_clobber_threshold";
 
@@ -13373,6 +14362,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION =
                 "override_settings_provider_restore_any_version";
         /**
@@ -13383,6 +14373,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CHAINED_BATTERY_ATTRIBUTION_ENABLED =
                 "chained_battery_attribution_enabled";
 
@@ -13395,6 +14386,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT =
                 "enable_adb_incremental_install_default";
 
@@ -13412,6 +14404,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
                 "autofill_compat_mode_allowed_packages";
 
@@ -13425,6 +14418,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_LOGGING_LEVEL = "autofill_logging_level";
 
         /**
@@ -13432,6 +14426,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_MAX_PARTITIONS_SIZE = "autofill_max_partitions_size";
 
         /**
@@ -13440,6 +14435,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
 
         /**
@@ -13448,6 +14444,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS =
                 "hidden_api_blacklist_exemptions";
 
@@ -13460,14 +14457,16 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDDEN_API_POLICY = "hidden_api_policy";
 
-         /**
+        /**
          * Flag for forcing {@link com.android.server.compat.OverrideValidatorImpl}
          * to consider this a non-debuggable build.
          *
          * @hide
          */
+        @Readable
         public static final String FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT =
                 "force_non_debuggable_final_build_for_compat";
 
@@ -13477,6 +14476,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SIGNED_CONFIG_VERSION = "signed_config_version";
 
         /**
@@ -13485,6 +14485,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT =
                 "sound_trigger_detection_service_op_timeout";
 
@@ -13494,6 +14495,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY =
                 "max_sound_trigger_detection_service_ops_per_day";
 
@@ -13501,6 +14503,7 @@
          * Indicates whether aware is available in the current location.
          * @hide
          */
+        @Readable
         public static final String AWARE_ALLOWED = "aware_allowed";
 
         /**
@@ -13509,6 +14512,7 @@
          * Used by PhoneWindowManager.
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_LONG_PRESS =
                 "power_button_long_press";
 
@@ -13518,6 +14522,7 @@
          * Used by PhoneWindowManager.
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_VERY_LONG_PRESS =
                 "power_button_very_long_press";
 
@@ -13543,7 +14548,8 @@
                     CONTENT_URI,
                     CALL_METHOD_GET_GLOBAL,
                     CALL_METHOD_PUT_GLOBAL,
-                    sProviderHolder);
+                    sProviderHolder,
+                    Global.class);
 
         // Certain settings have been moved from global to the per-user secure namespace
         @UnsupportedAppUsage
@@ -13572,6 +14578,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(Global.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -13981,6 +14992,7 @@
           * Subscription Id to be used for voice call on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_VOICE_CALL_SUBSCRIPTION = "multi_sim_voice_call";
 
         /**
@@ -13989,18 +15001,21 @@
           * @hide
           */
         @UnsupportedAppUsage
+        @Readable
         public static final String MULTI_SIM_VOICE_PROMPT = "multi_sim_voice_prompt";
 
         /**
           * Subscription Id to be used for data call on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_DATA_CALL_SUBSCRIPTION = "multi_sim_data_call";
 
         /**
           * Subscription Id to be used for SMS on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_SMS_SUBSCRIPTION = "multi_sim_sms";
 
         /**
@@ -14008,6 +15023,7 @@
           * The value 1 - enable, 0 - disable
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_SMS_PROMPT = "multi_sim_sms_prompt";
 
         /** User preferred subscriptions setting.
@@ -14017,6 +15033,7 @@
           * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String[] MULTI_SIM_USER_PREFERRED_SUBS = {"user_preferred_sub1",
                 "user_preferred_sub2","user_preferred_sub3"};
 
@@ -14024,6 +15041,7 @@
          * Which subscription is enabled for a physical slot.
          * @hide
          */
+        @Readable
         public static final String ENABLED_SUBSCRIPTION_FOR_SLOT = "enabled_subscription_for_slot";
 
         /**
@@ -14031,6 +15049,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String MODEM_STACK_ENABLED_FOR_SLOT = "modem_stack_enabled_for_slot";
 
         /**
@@ -14038,6 +15057,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NEW_CONTACT_AGGREGATOR = "new_contact_aggregator";
 
         /**
@@ -14047,12 +15067,14 @@
          * @removed
          */
         @Deprecated
+        @Readable
         public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
 
         /**
          * Whether to enable contacts metadata syncing or not
          * The value 1 - enable, 0 - disable
          */
+        @Readable
         public static final String CONTACT_METADATA_SYNC_ENABLED = "contact_metadata_sync_enabled";
 
         /**
@@ -14060,6 +15082,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String ENABLE_CELLULAR_ON_BOOT = "enable_cellular_on_boot";
 
         /**
@@ -14068,6 +15091,7 @@
          * Should be a float, and includes updates only.
          * @hide
          */
+        @Readable
         public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
 
         /**
@@ -14076,6 +15100,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTIFICATION_CHANNEL_WARNINGS =
                 "show_notification_channel_warnings";
 
@@ -14083,6 +15108,7 @@
          * Whether cell is enabled/disabled
          * @hide
          */
+        @Readable
         public static final String CELL_ON = "cell_on";
 
         /**
@@ -14111,30 +15137,35 @@
          * Whether to show the high temperature warning notification.
          * @hide
          */
+        @Readable
         public static final String SHOW_TEMPERATURE_WARNING = "show_temperature_warning";
 
         /**
          * Whether to show the usb high temperature alarm notification.
          * @hide
          */
+        @Readable
         public static final String SHOW_USB_TEMPERATURE_ALARM = "show_usb_temperature_alarm";
 
         /**
          * Temperature at which the high temperature warning notification should be shown.
          * @hide
          */
+        @Readable
         public static final String WARNING_TEMPERATURE = "warning_temperature";
 
         /**
          * Whether the diskstats logging task is enabled/disabled.
          * @hide
          */
+        @Readable
         public static final String ENABLE_DISKSTATS_LOGGING = "enable_diskstats_logging";
 
         /**
          * Whether the cache quota calculation task is enabled/disabled.
          * @hide
          */
+        @Readable
         public static final String ENABLE_CACHE_QUOTA_CALCULATION =
                 "enable_cache_quota_calculation";
 
@@ -14142,6 +15173,7 @@
          * Whether the Deletion Helper no threshold toggle is available.
          * @hide
          */
+        @Readable
         public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE =
                 "enable_deletion_helper_no_threshold_toggle";
 
@@ -14162,6 +15194,7 @@
          * Options will be used in order up to the maximum allowed by the UI.
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_SNOOZE_OPTIONS =
                 "notification_snooze_options";
 
@@ -14173,6 +15206,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_FEEDBACK_ENABLED = "notification_feedback_enabled";
 
         /**
@@ -14184,6 +15218,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT =
                 "blocking_helper_dismiss_to_view_ratio";
 
@@ -14195,6 +15230,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKING_HELPER_STREAK_LIMIT = "blocking_helper_streak_limit";
 
         /**
@@ -14222,6 +15258,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SQLITE_COMPATIBILITY_WAL_FLAGS =
                 "sqlite_compatibility_wal_flags";
 
@@ -14231,6 +15268,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String ENABLE_GNSS_RAW_MEAS_FULL_TRACKING =
                 "enable_gnss_raw_meas_full_tracking";
 
@@ -14242,6 +15280,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT =
                 "install_carrier_app_notification_persistent";
 
@@ -14253,6 +15292,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS =
                 "install_carrier_app_notification_sleep_millis";
 
@@ -14262,6 +15302,7 @@
          * everything else is unspecified.
          * @hide
          */
+        @Readable
         public static final String ZRAM_ENABLED =
                 "zram_enabled";
 
@@ -14271,6 +15312,7 @@
          * "device_default" will let the system decide whether to enable the freezer or not
          * @hide
          */
+        @Readable
         public static final String CACHED_APPS_FREEZER_ENABLED = "cached_apps_freezer";
 
         /**
@@ -14293,6 +15335,7 @@
          * @see com.android.systemui.statusbar.policy.SmartReplyConstants
          * @hide
          */
+        @Readable
         public static final String SMART_REPLIES_IN_NOTIFICATIONS_FLAGS =
                 "smart_replies_in_notifications_flags";
 
@@ -14309,6 +15352,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS =
                 "smart_suggestions_in_notifications_flags";
 
@@ -14318,6 +15362,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_FIRST_CRASH_DIALOG = "show_first_crash_dialog";
 
@@ -14325,6 +15370,7 @@
          * If nonzero, crash dialogs will show an option to restart the app.
          * @hide
          */
+        @Readable
         public static final String SHOW_RESTART_IN_CRASH_DIALOG = "show_restart_in_crash_dialog";
 
         /**
@@ -14332,6 +15378,7 @@
          * this app.
          * @hide
          */
+        @Readable
         public static final String SHOW_MUTE_IN_CRASH_DIALOG = "show_mute_in_crash_dialog";
 
 
@@ -14387,6 +15434,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BACKUP_AGENT_TIMEOUT_PARAMETERS =
                 "backup_agent_timeout_parameters";
 
@@ -14401,6 +15449,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GNSS_SATELLITE_BLOCKLIST = "gnss_satellite_blocklist";
 
         /**
@@ -14412,6 +15461,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS =
                 "gnss_hal_location_request_duration_millis";
 
@@ -14428,6 +15478,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BINDER_CALLS_STATS = "binder_calls_stats";
 
         /**
@@ -14441,6 +15492,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOOPER_STATS = "looper_stats";
 
         /**
@@ -14455,6 +15507,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KERNEL_CPU_THREAD_READER = "kernel_cpu_thread_reader";
 
         /**
@@ -14462,6 +15515,7 @@
          * reboot. The value "1" enables native flags health check; otherwise it's disabled.
          * @hide
          */
+        @Readable
         public static final String NATIVE_FLAGS_HEALTH_CHECK_ENABLED =
                 "native_flags_health_check_enabled";
 
@@ -14471,6 +15525,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_MODE = "mode";
 
         /**
@@ -14480,6 +15535,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_BASE_INTERVAL_MILLIS = "baseIntervalMillis";
 
         /**
@@ -14488,6 +15544,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_INTERVAL_MULTIPLIER = "intervalMultiplier";
 
         /**
@@ -14509,6 +15566,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_PARAMETERS =
                 "appop_history_parameters";
 
@@ -14526,6 +15584,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTO_REVOKE_PARAMETERS =
                 "auto_revoke_parameters";
 
@@ -14537,6 +15596,7 @@
          * @see com.android.internal.os.BatteryStatsImpl.Constants.KEY_BATTERY_CHARGED_DELAY_MS
          * @hide
          */
+        @Readable
         public static final String BATTERY_CHARGING_STATE_UPDATE_DELAY =
                 "battery_charging_state_update_delay";
 
@@ -14545,6 +15605,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS =
                 "text_classifier_action_model_params";
 
@@ -14558,6 +15619,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE =
                 "power_button_suppression_delay_after_gesture_wake";
 
@@ -14566,6 +15628,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADVANCED_BATTERY_USAGE_AMOUNT = "advanced_battery_usage_amount";
 
         /**
@@ -14580,6 +15643,7 @@
          * 2: always on - All 5G NSA tracking indications are on whether the screen is on or off.
          * @hide
          */
+        @Readable
         public static final String NR_NSA_TRACKING_SCREEN_OFF_MODE =
                 "nr_nsa_tracking_screen_off_mode";
 
@@ -14590,6 +15654,7 @@
          * 1: Enabled
          * @hide
          */
+        @Readable
         public static final String SHOW_PEOPLE_SPACE = "show_people_space";
 
         /**
@@ -14600,6 +15665,7 @@
          * 2: All conversations
          * @hide
          */
+        @Readable
         public static final String PEOPLE_SPACE_CONVERSATION_TYPE =
                 "people_space_conversation_type";
 
@@ -14610,6 +15676,7 @@
          * 1: Enabled
          * @hide
          */
+        @Readable
         public static final String SHOW_NEW_LOCKSCREEN = "show_new_lockscreen";
 
         /**
@@ -14619,6 +15686,7 @@
          * 1: Enabled
          * @hide
          */
+        @Readable
         public static final String SHOW_NEW_NOTIF_DISMISS = "show_new_notif_dismiss";
 
         /**
@@ -14633,6 +15701,7 @@
          * 1: Enabled (All apps will receive the new rules)
          * @hide
          */
+        @Readable
         public static final String BACKPORT_S_NOTIF_RULES = "backport_s_notif_rules";
 
         /**
@@ -14676,6 +15745,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCK_UNTRUSTED_TOUCHES_MODE = "block_untrusted_touches";
 
         /**
@@ -14702,6 +15772,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH =
                 "maximum_obscuring_opacity_for_touch";
 
@@ -14714,6 +15785,7 @@
          * 1: enabled
          * @hide
          */
+        @Readable
         public static final String RESTRICTED_NETWORKING_MODE = "restricted_networking_mode";
     }
 
@@ -14735,7 +15807,8 @@
                 CALL_METHOD_PUT_CONFIG,
                 CALL_METHOD_LIST_CONFIG,
                 CALL_METHOD_SET_ALL_CONFIG,
-                sProviderHolder);
+                sProviderHolder,
+                Config.class);
 
         /**
          * Look up a name in the database.
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
index 197c5a6..de2c6f77 100644
--- a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -48,12 +48,12 @@
  *   // Unable to bind: handle error.
  * }
  * </code>
- * <p> Upon completion {@link #disposeConnection} should be called to unbind the
+ * <p> Upon completion {@link #disconnect} should be called to unbind the
  * CarrierMessagingService.
  * @hide
  */
 @SystemApi
-public final class CarrierMessagingServiceWrapper {
+public final class CarrierMessagingServiceWrapper implements AutoCloseable {
     // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
     // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
     private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
@@ -61,6 +61,7 @@
     private volatile ICarrierMessagingService mICarrierMessagingService;
     private Runnable mOnServiceReadyCallback;
     private Executor mServiceReadyCallbackExecutor;
+    private Context mContext;
 
     /**
      * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
@@ -89,6 +90,7 @@
         mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
         mOnServiceReadyCallback = onServiceReadyCallback;
         mServiceReadyCallbackExecutor = executor;
+        mContext = context;
         return context.bindService(intent, mCarrierMessagingServiceConnection,
                 Context.BIND_AUTO_CREATE);
     }
@@ -96,13 +98,12 @@
     /**
      * Unbinds the carrier messaging service. This method should be called exactly once.
      *
-     * @param context the context
      * @hide
      */
     @SystemApi
-    public void disposeConnection(@NonNull Context context) {
+    public void disconnect() {
         Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
-        context.unbindService(mCarrierMessagingServiceConnection);
+        mContext.unbindService(mCarrierMessagingServiceConnection);
         mCarrierMessagingServiceConnection = null;
         mOnServiceReadyCallback = null;
         mServiceReadyCallbackExecutor = null;
@@ -291,6 +292,12 @@
         }
     }
 
+    /** @hide */
+    @Override
+    public void close() {
+        disconnect();
+    }
+
     /**
      * A basic {@link ServiceConnection}.
      */
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 01e5260..c41e599 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -150,7 +150,7 @@
     public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 1 << 1;
 
     /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
-     * should disable phone call sounds, buyt not notification sound.
+     * should disable phone call sounds, but not notification sound.
      * This does not change the interruption filter, only the effects. **/
     public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 1 << 2;
 
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 93b5fd4..9df213b 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -18,6 +18,7 @@
 
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -31,6 +32,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class AngleMeasurement implements Parcelable {
     private final double mRadians;
     private final double mErrorRadians;
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index 20a1c7a..3d8626b 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -28,6 +29,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class AngleOfArrivalMeasurement implements Parcelable {
     private final AngleMeasurement mAzimuthAngleMeasurement;
     private final AngleMeasurement mAltitudeAngleMeasurement;
@@ -53,7 +55,7 @@
      * @return the azimuth {@link AngleMeasurement}
      */
     @NonNull
-    public AngleMeasurement getAzimuthAngleMeasurement() {
+    public AngleMeasurement getAzimuth() {
         return mAzimuthAngleMeasurement;
     }
 
@@ -70,7 +72,7 @@
      * @return altitude {@link AngleMeasurement} or null when this is not available
      */
     @Nullable
-    public AngleMeasurement getAltitudeAngleMeasurement() {
+    public AngleMeasurement getAltitude() {
         return mAltitudeAngleMeasurement;
     }
 
@@ -85,8 +87,8 @@
 
         if (obj instanceof AngleOfArrivalMeasurement) {
             AngleOfArrivalMeasurement other = (AngleOfArrivalMeasurement) obj;
-            return mAzimuthAngleMeasurement.equals(other.getAzimuthAngleMeasurement())
-                    && mAltitudeAngleMeasurement.equals(other.getAltitudeAngleMeasurement());
+            return mAzimuthAngleMeasurement.equals(other.getAzimuth())
+                    && mAltitudeAngleMeasurement.equals(other.getAltitude());
         }
         return false;
     }
@@ -116,11 +118,9 @@
                 public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
                     Builder builder = new Builder();
 
-                    builder.setAzimuthAngleMeasurement(
-                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+                    builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader()));
 
-                    builder.setAltitudeAngleMeasurement(
-                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+                    builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader()));
 
                     return builder.build();
                 }
@@ -144,7 +144,7 @@
          * @param azimuthAngle azimuth angle
          */
         @NonNull
-        public Builder setAzimuthAngleMeasurement(@NonNull AngleMeasurement azimuthAngle) {
+        public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) {
             mAzimuthAngleMeasurement = azimuthAngle;
             return this;
         }
@@ -155,7 +155,7 @@
          * @param altitudeAngle altitude angle
          */
         @NonNull
-        public Builder setAltitudeAngleMeasurement(@NonNull AngleMeasurement altitudeAngle) {
+        public Builder setAltitude(@NonNull AngleMeasurement altitudeAngle) {
             mAltitudeAngleMeasurement = altitudeAngle;
             return this;
         }
diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java
index 10c2172..2a9bbdf 100644
--- a/core/java/android/uwb/DistanceMeasurement.java
+++ b/core/java/android/uwb/DistanceMeasurement.java
@@ -19,6 +19,7 @@
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -32,6 +33,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class DistanceMeasurement implements Parcelable {
     private final double mMeters;
     private final double mErrorMeters;
diff --git a/core/java/android/uwb/RangingMeasurement.java b/core/java/android/uwb/RangingMeasurement.java
index 50e5f0d..249e2b7 100644
--- a/core/java/android/uwb/RangingMeasurement.java
+++ b/core/java/android/uwb/RangingMeasurement.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
@@ -33,6 +34,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class RangingMeasurement implements Parcelable {
     private final UwbAddress mRemoteDeviceAddress;
     private final @Status int mStatus;
diff --git a/core/java/android/uwb/RangingReport.java b/core/java/android/uwb/RangingReport.java
index 5b5f084..7a2df86 100644
--- a/core/java/android/uwb/RangingReport.java
+++ b/core/java/android/uwb/RangingReport.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -30,6 +31,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class RangingReport implements Parcelable {
     private final List<RangingMeasurement> mRangingMeasurements;
 
diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java
index 0f87af4..bfa8bf2 100644
--- a/core/java/android/uwb/RangingSession.java
+++ b/core/java/android/uwb/RangingSession.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Binder;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
@@ -42,6 +43,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class RangingSession implements AutoCloseable {
     private static final String TAG = "Uwb.RangingSession";
     private final SessionHandle mSessionHandle;
diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java
index b9523a3..22883be 100644
--- a/core/java/android/uwb/UwbAddress.java
+++ b/core/java/android/uwb/UwbAddress.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -28,6 +29,7 @@
  *
  * @hide
  */
+@SystemApi
 public final class UwbAddress implements Parcelable {
     public static final int SHORT_ADDRESS_BYTE_LENGTH = 2;
     public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8;
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 15ee5b5..8adfe06 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.IBinder;
@@ -44,6 +45,7 @@
  *
  * @hide
  */
+@SystemApi
 @SystemService(Context.UWB_SERVICE)
 public final class UwbManager {
     private IUwbAdapter mUwbAdapter;
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 9e59e50..4a24358 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -339,8 +339,9 @@
             }
             mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
             mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile));
-            mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile,
+            mPowerCalculators.add(new SensorPowerCalculator(
                     mContext.getSystemService(SensorManager.class)));
+            mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile));
             mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
             mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
             mPowerCalculators.add(new MediaPowerCalculator(mPowerProfile));
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index e5d64a0..b8c066d 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -62,8 +62,9 @@
                 }
                 mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile));
-                mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile,
+                mPowerCalculators.add(new SensorPowerCalculator(
                         mContext.getSystemService(SensorManager.class)));
+                mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new AudioPowerCalculator(mPowerProfile));
diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java
new file mode 100644
index 0000000..9ea934a
--- /dev/null
+++ b/core/java/com/android/internal/os/GnssPowerCalculator.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.location.GnssSignalQuality;
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+import android.os.UidBatteryConsumer;
+import android.os.UserHandle;
+import android.util.SparseArray;
+
+import java.util.List;
+
+/**
+ * Estimates the amount of power consumed by the GNSS (e.g. GPS).
+ */
+public class GnssPowerCalculator extends PowerCalculator {
+    private final double mAveragePowerGnssOn;
+    private final double[] mAveragePowerPerSignalQuality;
+
+    public GnssPowerCalculator(PowerProfile profile) {
+        mAveragePowerGnssOn = profile.getAveragePowerOrDefault(PowerProfile.POWER_GPS_ON, -1);
+        mAveragePowerPerSignalQuality =
+                new double[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS];
+        for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
+            mAveragePowerPerSignalQuality[i] = profile.getAveragePower(
+                    PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i);
+        }
+    }
+
+    @Override
+    public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
+            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
+            SparseArray<UserHandle> asUsers) {
+        final double averageGnssPowerMa = getAverageGnssPower(batteryStats, rawRealtimeUs,
+                BatteryStats.STATS_SINCE_CHARGED);
+        final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
+                builder.getUidBatteryConsumerBuilders();
+        for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
+            final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
+            calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs, rawUptimeUs, query,
+                    averageGnssPowerMa);
+        }
+    }
+
+    private void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
+            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
+            double averageGnssPowerMa) {
+        final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
+        double powerMah = computePower(durationMs, averageGnssPowerMa);
+        app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS, durationMs)
+                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, powerMah);
+    }
+
+    @Override
+    public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
+            long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
+        double averageGnssPowerMa = getAverageGnssPower(batteryStats, rawRealtimeUs, statsType);
+        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);
+            }
+        }
+    }
+
+    protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
+            int statsType, double averageGnssPowerMa) {
+        final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
+        double powerMah = computePower(durationMs, averageGnssPowerMa);
+
+        app.gpsTimeMs = durationMs;
+        app.gpsPowerMah = powerMah;
+    }
+
+    private long computeDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
+        final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
+        final BatteryStats.Uid.Sensor sensor = sensorStats.get(BatteryStats.Uid.Sensor.GPS);
+        if (sensor == null) {
+            return 0;
+        }
+
+        final BatteryStats.Timer timer = sensor.getSensorTime();
+        return timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
+    }
+
+    private double computePower(long sensorTime, double averageGnssPowerMa) {
+        return (sensorTime * averageGnssPowerMa) / (1000 * 60 * 60);
+    }
+
+    private double getAverageGnssPower(BatteryStats stats, long rawRealtimeUs, int statsType) {
+        double averagePower = mAveragePowerGnssOn;
+        if (averagePower != -1) {
+            return averagePower;
+        }
+        averagePower = 0;
+        long totalTime = 0;
+        double totalPower = 0;
+        for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
+            long timePerLevel = stats.getGpsSignalQualityTime(i, rawRealtimeUs, statsType);
+            totalTime += timePerLevel;
+            totalPower += mAveragePowerPerSignalQuality[i] * timePerLevel;
+        }
+        if (totalTime != 0) {
+            averagePower = totalPower / totalTime;
+        }
+        return averagePower;
+    }
+}
diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java
index 9c8aafb..78c4fe2 100644
--- a/core/java/com/android/internal/os/SensorPowerCalculator.java
+++ b/core/java/com/android/internal/os/SensorPowerCalculator.java
@@ -17,81 +17,79 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.location.GnssSignalQuality;
+import android.os.BatteryConsumer;
 import android.os.BatteryStats;
-import android.os.UserHandle;
+import android.os.BatteryUsageStatsQuery;
+import android.os.UidBatteryConsumer;
 import android.util.SparseArray;
 
 import java.util.List;
 
 public class SensorPowerCalculator extends PowerCalculator {
-    private final PowerProfile mPowerProfile;
-    private final List<Sensor> mSensors;
-    private double mGpsPower;
+    private final SparseArray<Sensor> mSensors;
 
-    public SensorPowerCalculator(PowerProfile profile, SensorManager sensorManager) {
-        mPowerProfile = profile;
-        mSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+    public SensorPowerCalculator(SensorManager sensorManager) {
+        List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+        mSensors = new SparseArray<>(sensors.size());
+        for (int i = 0; i < sensors.size(); i++) {
+            Sensor sensor = sensors.get(i);
+            mSensors.put(sensor.getHandle(), sensor);
+        }
     }
 
     @Override
-    public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
-            long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
-        mGpsPower = getAverageGpsPower(batteryStats, rawRealtimeUs, statsType);
-        super.calculate(sippers, batteryStats, rawRealtimeUs, rawUptimeUs, statsType, asUsers);
+    protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
+            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
+        app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SENSORS,
+                        calculateDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED))
+                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS,
+                        calculatePowerMah(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED));
     }
 
     @Override
     protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
             long rawUptimeUs, int statsType) {
-        // Process Sensor usage
+        app.sensorPowerMah = calculatePowerMah(u, rawRealtimeUs, statsType);
+    }
+
+    private long calculateDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
+        long durationMs = 0;
         final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
         final int NSE = sensorStats.size();
         for (int ise = 0; ise < NSE; ise++) {
-            final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
             final int sensorHandle = sensorStats.keyAt(ise);
-            final BatteryStats.Timer timer = sensor.getSensorTime();
-            final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
-
-            switch (sensorHandle) {
-                case BatteryStats.Uid.Sensor.GPS:
-                    app.gpsTimeMs = sensorTime;
-                    app.gpsPowerMah = (app.gpsTimeMs * mGpsPower) / (1000 * 60 * 60);
-                    break;
-                default:
-                    final int sensorsCount = mSensors.size();
-                    for (int i = 0; i < sensorsCount; i++) {
-                        final Sensor s = mSensors.get(i);
-                        if (s.getHandle() == sensorHandle) {
-                            app.sensorPowerMah += (sensorTime * s.getPower()) / (1000 * 60 * 60);
-                            break;
-                        }
-                    }
-                    break;
+            if (sensorHandle == BatteryStats.Uid.Sensor.GPS) {
+                continue;
             }
+
+            final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
+            final BatteryStats.Timer timer = sensor.getSensorTime();
+            durationMs += timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
         }
+        return durationMs;
     }
 
-    private double getAverageGpsPower(BatteryStats stats, long rawRealtimeUs,
-            int statsType) {
-        double averagePower =
-                mPowerProfile.getAveragePowerOrDefault(PowerProfile.POWER_GPS_ON, -1);
-        if (averagePower != -1) {
-            return averagePower;
+    private double calculatePowerMah(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
+        double powerMah = 0;
+        final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
+        final int count = sensorStats.size();
+        for (int ise = 0; ise < count; ise++) {
+            final int sensorHandle = sensorStats.keyAt(ise);
+            // TODO(b/178127364): remove BatteryStats.Uid.Sensor.GPS and references to it.
+            if (sensorHandle == BatteryStats.Uid.Sensor.GPS) {
+                continue;
+            }
+
+            final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
+            final BatteryStats.Timer timer = sensor.getSensorTime();
+            final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
+            if (sensorTime != 0) {
+                Sensor s = mSensors.get(sensorHandle);
+                if (s != null) {
+                    powerMah += (sensorTime * s.getPower()) / (1000 * 60 * 60);
+                }
+            }
         }
-        averagePower = 0;
-        long totalTime = 0;
-        double totalPower = 0;
-        for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
-            long timePerLevel = stats.getGpsSignalQualityTime(i, rawRealtimeUs, statsType);
-            totalTime += timePerLevel;
-            totalPower +=
-                    mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
-                            * timePerLevel;
-        }
-        if (totalTime != 0) {
-            averagePower = totalPower / totalTime;
-        }
-        return averagePower;
+        return powerMah;
     }
 }
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 8dc56ed..94bd28a 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1023,7 +1023,9 @@
     audio_channel_mask_t nMask;
     jint jMask;
 
-    int gainIndex = nAudioPortConfig->gain.index;
+    int gainIndex = (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
+            ? nAudioPortConfig->gain.index
+            : -1;
     if (gainIndex >= 0) {
         ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
               gainIndex, nAudioPortConfig->gain.mode);
@@ -1120,7 +1122,9 @@
             goto exit;
         }
     }
-    nMask = nAudioPortConfig->channel_mask;
+    nMask = (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)
+            ? nAudioPortConfig->channel_mask
+            : AUDIO_CONFIG_BASE_INITIALIZER.channel_mask;
     if (useInMask) {
         jMask = inChannelMaskFromNative(nMask);
         ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
@@ -1129,12 +1133,17 @@
         ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
     }
 
-    *jAudioPortConfig = env->NewObject(clazz, methodID,
-                                       jAudioPort,
-                                       nAudioPortConfig->sample_rate,
-                                       jMask,
-                                       audioFormatFromNative(nAudioPortConfig->format),
-                                       jAudioGainConfig);
+    *jAudioPortConfig =
+            env->NewObject(clazz, methodID, jAudioPort,
+                           (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)
+                                   ? nAudioPortConfig->sample_rate
+                                   : AUDIO_CONFIG_BASE_INITIALIZER.sample_rate,
+                           jMask,
+                           audioFormatFromNative(
+                                   (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)
+                                           ? nAudioPortConfig->format
+                                           : AUDIO_CONFIG_BASE_INITIALIZER.format),
+                           jAudioGainConfig);
     if (*jAudioPortConfig == NULL) {
         ALOGV("convertAudioPortConfigFromNative could not create new port config");
         jStatus = (jint)AUDIO_JAVA_ERROR;
@@ -1936,6 +1945,7 @@
     nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
 
     jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
+    nAudioMix->mFormat = AUDIO_CONFIG_INITIALIZER;
     nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
                                                      gAudioFormatFields.mSampleRate);
     nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index 12d8bc6..bddcae8 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -86,25 +86,31 @@
         return 0;
     }
 
-    std::shared_ptr<KeyCharacterMap> kcm = KeyCharacterMap::readFromParcel(parcel);
-    if (!kcm.get()) {
-        return 0;
+    std::shared_ptr<KeyCharacterMap> kcm = nullptr;
+    // Check if map is a null character map
+    if (parcel->readBool()) {
+        kcm = KeyCharacterMap::readFromParcel(parcel);
+        if (!kcm.get()) {
+            return 0;
+        }
     }
-
     NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, kcm);
     return reinterpret_cast<jlong>(map);
 }
 
 static void nativeWriteToParcel(JNIEnv* env, jobject clazz, jlong ptr, jobject parcelObj) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
-    if (!map->getMap()) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (!parcel) {
         return;
     }
-    Parcel* parcel = parcelForJavaObject(env, parcelObj);
-    if (parcel) {
-        parcel->writeInt32(map->getDeviceId());
-        map->getMap()->writeToParcel(parcel);
+    parcel->writeInt32(map->getDeviceId());
+    if (!map || !map->getMap()) {
+        parcel->writeBool(false);
+        return;
     }
+    parcel->writeBool(true);
+    map->getMap()->writeToParcel(parcel);
 }
 
 static void nativeDispose(JNIEnv *env, jobject clazz, jlong ptr) {
@@ -112,15 +118,22 @@
     delete map;
 }
 
+// Return the associated character or combining accent, or 0 if none.
 static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jlong ptr,
         jint keyCode, jint metaState) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
+    if (!map || !map->getMap()) {
+        return static_cast<jchar>(0);
+    }
     return map->getMap()->getCharacter(keyCode, metaState);
 }
 
 static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
         jint metaState, jobject fallbackActionObj) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
+    if (!map || !map->getMap()) {
+        return static_cast<jboolean>(false);
+    }
     KeyCharacterMap::FallbackAction fallbackAction;
 
     bool result = map->getMap()->getFallbackAction(keyCode, metaState, &fallbackAction);
@@ -133,15 +146,22 @@
     return result;
 }
 
+// Return the number of a key code, or 0 if none.
 static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
+    if (!map || !map->getMap()) {
+        return static_cast<jchar>(0);
+    }
     return map->getMap()->getNumber(keyCode);
 }
 
+// Return the matched key code and meta state, or 0 if none.
 static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
         jcharArray charsArray, jint metaState) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
-
+    if (!map || !map->getMap()) {
+        return static_cast<jchar>(0);
+    }
     jsize numChars = env->GetArrayLength(charsArray);
     jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
     if (!chars) {
@@ -155,20 +175,30 @@
     return result;
 }
 
+// Return the associated display label, or 0 if none.
 static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
+    if (!map || !map->getMap()) {
+        return static_cast<jchar>(0);
+    }
     return map->getMap()->getDisplayLabel(keyCode);
 }
 
+// Return the associated keyboard type, or 0 if none.
 static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jlong ptr) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
+    if (!map || !map->getMap()) {
+        return static_cast<jint>(0);
+    }
     return static_cast<jint>(map->getMap()->getKeyboardType());
 }
 
 static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
         jcharArray charsArray) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
-
+    if (!map || !map->getMap()) {
+        return env->NewObjectArray(0 /* size */, gKeyEventClassInfo.clazz, NULL);
+    }
     jchar* chars = env->GetCharArrayElements(charsArray, NULL);
     if (!chars) {
         return NULL;
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index abbe25d..c580b34 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -283,6 +283,7 @@
         optional SettingProto emulate_display_cutout = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto force_desktop_mode_on_external_displays = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto enable_sizecompat_freeform = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto enable_non_resizable_multi_window = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Development development = 39;
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 29dc5a7..f543373 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -689,6 +689,10 @@
     <!-- Made protected in S (was added in R) -->
     <protected-broadcast android:name="com.android.internal.intent.action.BUGREPORT_REQUESTED" />
 
+    <!-- Added in S -->
+    <protected-broadcast android:name="android.app.action.MANAGED_PROFILE_CREATED" />
+    <protected-broadcast android:name="android.app.action.PROVISIONED_MANAGED_DEVICE" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index bd017fd..eb45a6a 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Inkomender beller-ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Versteek uitgaande beller-ID"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID van gekoppelde lyn"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Beperking op ID van gekoppelde lyn"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Oproepaanstuur"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensorkennisgewingdiens"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Skemerdiens"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tydsonebespeurder (geen konnektiwiteit nie)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Jy kan nou jou hele skerm of \'n deel daarvan vergroot"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Skakel aan in Instellings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Maak toe"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4955e47..60157bd 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"የገቢ ደዋይID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"የወጪ የደዋይ መታወቂያውን ደብቅ"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"የተገናኘ መስመር መታወቂያ"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"የተገናኘ መስመር መታወቂያ ገደብ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"ጥሪ ማስተላለፍ"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"የዳሳሽ ማሳወቂያ አገልግሎት"</string>
     <string name="twilight_service" msgid="8964898045693187224">"የውጋገን አገልግሎት"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"የሰዓት ሰቅ አንባቢ (ግንኙነት የለም)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"አሁን የተወሰነ ወይም ሁሉንም ማያ ገጽዎን ማጉላት ይችላሉ"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"በቅንብሮች ውስጥ ያብሩ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"አሰናብት"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 770c304..4469117 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -61,8 +61,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"معرف المتصل الوارد"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"إخفاء إظهار رقم المتّصل للمكالمات الصادرة"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"معرّف الخط المتصل"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"تقييد معرّف الخط المتصل"</string>
     <string name="CfMmi" msgid="8390012691099787178">"إعادة توجيه المكالمة"</string>
@@ -212,6 +211,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"خدمة إشعارات جهاز الاستشعار"</string>
     <string name="twilight_service" msgid="8964898045693187224">"خدمة الغسق"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"أداة التعرّف على المنطقة الزمنية (ليس هناك حاجة للاتصال بالشبكة)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2340,4 +2341,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"يمكنك الآن تكبير الشاشة كلها أو جزء منها."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"التفعيل من خلال \"الإعدادات\""</string>
     <string name="dismiss_action" msgid="1728820550388704784">"إغلاق"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 2e23ee4..c413c33 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"অন্তৰ্গামী কলাৰ আইডি"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"বহিৰ্গামী কলাৰ আইডি লুকুৱাওক"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"সংযোজিত লাইন আইডি"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"সংযোজিত লাইন আইডিৰ সীমাবদ্ধতা"</string>
     <string name="CfMmi" msgid="8390012691099787178">"কল ফৰৱাৰ্ডিং"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"ছেন্সৰ জাননী সেৱা"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight সেৱা"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"সময় মণ্ডল চিনাক্তকাৰী (সংযোগ নাই)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"আপুনি সকলো অথবা কেইখনমান স্ক্ৰীন বিবৰ্ধন কৰিব পাৰে"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ছেটিঙত অন কৰক"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"অগ্ৰাহ্য কৰক"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 475fa7d..f7e4169 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Gələn çağrı kimliyi"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Gedən Zəng edən ID-sini gizlədin"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Qoşulmuş Xətt ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Qoşulmuş Xətt ID Məhdudluğu"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Zəng yönləndirmə"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Bildiriş Xidməti"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"İndi ekranı qismən və ya tam şəkildə böyüdə 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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 6378045..76a278a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Dolazni ID pozivaoca"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Sakrijte ID odlaznog pozivaoca"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID povezane linije"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ograničenje ID-a povezane linije"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Preusmeravanje poziva"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Usluga obaveštenja senzora"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Možete da uvećate deo ekrana ili ceo ekran"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Podešavanjima"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 80c071c..deb9218 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Ідэнтыфікатар АВН"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Схаваць ідэнтыфікатар абанента выходнага выкліку"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Ідэнтыфікатар падлучанай лініі"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Абмежаванне ідэнтыфікатара падлучанай лініі"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Пераадрасацыя выкліку"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Служба апавяшчэнняў датчыка"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Служба Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Дэтэктар часавога пояса (няма падключэння)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Цяпер можна павялічваць увесь экран ці яго частку."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Уключыць у Наладах"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Адхіліць"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 6dd7b6a6..9ee0d99 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Идентификация на вх. обаждания"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Скриване на изходящия идентификатор на обаждащия се"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Идентификация на свързаната линия"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ограничение за идентификацията на свързаната линия"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Пренасочване на повиквания"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга за известия за сензорите"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Услуга Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Инструмент за установяване на часовата зона (няма връзка)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Можете да увеличите целия екран или част от него"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включете от настройките"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Отхвърляне"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index ff9b003..3ce96c7 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"আগত কলার আইডি"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"আউটগোয়িং কলার আইডি আড়াল করুন"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"সংযুক্ত লাইন ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"সংযুক্ত লাইন ID-র বিধিনিষেধ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"কল ফরওয়ার্ড করা"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"সেন্সর বিজ্ঞপ্তি পরিষেবা"</string>
     <string name="twilight_service" msgid="8964898045693187224">"গোধূলি পরিষেবা"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"টাইম জোন ডিটেক্টর (কানেকশন নেই)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"এখন আপনি কিছু বা সবকটি স্ক্রিন বড় করে দেখতে পারেন"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"সেটিংস থেকে চালু করুন"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"বাতিল করুন"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index d2a4f7d..51ca3da 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID dolaznog poziva"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Sakrij odlazni ID pozivaoca"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Identifikacija povezane linije"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ograničenje identifikacije povezane linije"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Prosljeđivanje poziva"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Usluga obavještavanja putem senzora"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sada možete uvećati dio ekrana ili cijeli ekran"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 47be220..6d81104 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Identificador de trucada (trucada entrant)"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Amaga l\'identificador de trucada sortint"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Identificador de la línia connectada"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restricció de l\'identificador de la línia connectada"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Desviació de trucades"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Servei de notificacions de sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -971,7 +972,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Permet que l\'aplicació modifiqui l\'historial del navegador o els marcadors de la tauleta. Això pot permetre que l\'aplicació esborri o modifiqui les dades del navegador. Nota: És possible que aquest permís no s\'apliqui a navegadors de tercers o a altres aplicacions amb capacitats de navegació web."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Permet que l\'aplicació modifiqui l\'historial o les adreces d\'interès que hagis desat al dispositiu Android TV. D\'aquesta manera, l\'aplicació pot esborrar o modificar les dades del navegador. Nota: és possible que aquest permís no s\'apliqui a navegadors de tercers ni a altres aplicacions amb funcions de navegació web."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Permet que l\'aplicació modifiqui l\'historial del navegador o els marcadors del telèfon. Això pot permetre que l\'aplicació esborri o modifiqui les dades del navegador. Nota: És possible que aquest permís no s\'apliqui a navegadors de tercers o a altres aplicacions amb capacitats de navegació web."</string>
-    <string name="permlab_setAlarm" msgid="1158001610254173567">"configuració d\'una alarma"</string>
+    <string name="permlab_setAlarm" msgid="1158001610254173567">"configurar una alarma"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"Permet que l\'aplicació defineixi una alarma en una aplicació de despertador instal·lada. És possible que algunes aplicacions de despertador no incorporin aquesta funció."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"afegeix bústia de veu"</string>
     <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Permet que l\'aplicació afegeixi missatges a la safata d\'entrada de la bústia de veu."</string>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ara pots ampliar la pantalla completa o una part"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activa a Configuració"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e7e4cc9..00b607c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Příchozí ID volajícího"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Skrýt ID volajícího u odchozího hovoru"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID připojené linky"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Omezení ID připojené linky"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Přesměrování hovorů"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Služba oznámení ze senzoru"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nyní můžete zvětšit celou obrazovku nebo její část"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnout v Nastavení"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Zavřít"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 47416cf..6e9a7e7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI-nummer"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Indgående opkalds-id"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Skjul Vis nummer (udgående opkald)"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Id for opkaldsmodtager"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Id for opkaldsmodtager er skjult"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Viderestilling af opkald"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Tjenesten Sensor Notification"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Tjenesten Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidszoneregistrering (ingen forbindelse)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2206,4 +2207,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Du kan nu forstørre dele af eller hele skærmen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivér i Indstillinger"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Luk"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0c2cfbf..82123d8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -204,6 +204,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2206,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Du kannst das Display teilweise oder ganz vergrößern"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"In den Einstellungen aktivieren"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Schließen"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b759be6..614fc95 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Εισερχόμενη αναγνώριση κλήσης"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Απόκρυψη εξερχόμενης αναγνώρισης κλήσης"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Αναγνωριστικό συνδεδεμένης γραμμής"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Περιορισμός αναγνωριστικού συνδεδεμένης πρόσβασης"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Προώθηση κλήσεων"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Υπηρεσία ειδοποίησης αισθητήρα"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Υπηρεσία Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Εντοπισμός ζώνης ώρας (χωρίς συνδεσιμότητα)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Μεγεθύνετε μέρος ή ολόκληρη την οθόνη σας"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ενεργοποίηση στις Ρυθμίσεις"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Παράβλεψη"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 52baecf..10ec8d0 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index c99fc18..bb7cd12 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d12f810..14c0a32 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f781191..5b6be71 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"You can now magnify some or all of your screen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 4a87b1e..b39bf9c 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎Sensor Notification Service‎‏‎‎‏‎"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎You can now magnify some or all of your screen‎‏‎‎‏‎"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎Turn on in Settings‎‏‎‎‏‎"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎Dismiss‎‏‎‎‏‎"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index bf4c0f6..d47430e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Servicio de notificaciones del sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Puedes ampliar toda tu pantalla o parte de ella"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Descartar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 08555e8..e84fd00 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID de emisor de llamada entrante"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ocultar ID de las llamadas salientes"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID de línea conectada"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restricción de ID de línea conectada"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Desvío de llamadas"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Servicio de notificación de sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ahora puedes ampliar toda la pantalla o una parte"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Ajustes"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Cerrar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 4818589..f7d053d 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Sissetuleva kõne helistaja ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Väljamineva helistaja ID peitmine"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Ühendatud liini ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ühendatud liini ID piiramine"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Kõnede suunamine"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Anduri märguande teenus"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nüüd saab suurendada kogu ekraanikuva või osa sellest"</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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 39fc77c..b22a777 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI zk."</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Sarrerako deien identifikazio-zerbitzua"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ezkutatu irteerako deitzailearen IDa"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Konektatutako linearen IDa"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Konektatutako linearen ID murriztapena"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Dei-desbideratzea"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sentsorearen jakinarazpen-zerbitzua"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Orain, pantaila osoa edo haren zati bat handi dezakezu"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktibatu ezarpenetan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Baztertu"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 935d679..084250e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"شناسه تماس‌گیرنده ورودی"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"پنهان کردن شناسه تماس‌گیرنده خروجی"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"شناسه خط متصل"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"محدودیت شناسه خط متصل"</string>
     <string name="CfMmi" msgid="8390012691099787178">"هدایت تماس"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"سرویس اعلان حسگر"</string>
     <string name="twilight_service" msgid="8964898045693187224">"‏سرویس Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"شناساگر منطقه زمانی (بدون اتصال)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"اکنون می‌توانید بخشی از صفحه یا کل آن را درشت کنید"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"روشن کردن در «تنظیمات»"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"رد شدن"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 09f289a..159e1b4 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI-koodi"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Soittajan tunnus"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Piilota soittajan tunnus (lähtevät puhelut)"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Yhteyslinjan tunnus"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Yhteyslinjan tunnuksen rajoitus"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Soitonsiirto"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Anturin ilmoituspalvelu"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Voit nyt suurentaa näytön osittain tai kokonaan"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Laita päälle asetuksista"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hylkää"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 6bedfca..fded10d 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -57,8 +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>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Masquer l\'identifiant de l\'appelant sortant"</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 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Service de notification de capteur"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Vous pouvez agrandir une partie ou la totalité de votre écran"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d8edc5d..b6eade2 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"Code IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"Code MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Numéro de l\'appelant (entrant)"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Masquer le numéro 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 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Service de notification du capteur"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Vous pouvez agrandir tout ou partie de l\'écran"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 76ab6ab..04b4236 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Identificador de chamada entrante"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ocultar identificador de chamada saínte"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID de liña conectada"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restrición de ID de liña conectada"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Desvío de chamadas"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Servizo de notificacións dos sensores"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora podes ampliar toda a pantalla ou parte dela"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fb7511a..7bab2ad 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"આવનાર કૉલર ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"આઉટગોઇંગ કૉલર ID છુપાવો"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"કનેક્ટ કરેલ લાઇન ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"કનેક્ટ કરેલ લાઇન ID પ્રતિબંધ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"કૉલ ફોર્વર્ડિંગ"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"સેન્સર નોટિફિકેશન સેવા"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ટ્વાઇલાઇટ સેવા"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"સમય ઝોન શોધવાની સુવિધા (કનેક્ટિવિટી જરૂરી નથી)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"હવે તમે તમારી કેટલીક કે આખી સ્ક્રીનને મોટી કરી શકો છો"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"સેટિંગમાં ચાલુ કરો"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"છોડી દો"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a094117..dbdfd4a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"आईएमईआई"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"इनकमिंग कॉलर आईडी"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"आउटगोइंग कॉल करने पर अपना कॉलर आईडी छिपाएं"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"कनेक्ट किया गया लाइन आईडी"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"कनेक्ट किया गया लाइन आईडी प्रतिबंध"</string>
     <string name="CfMmi" msgid="8390012691099787178">"कॉल आगे भेजना"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"सेंसर से जुड़ी सूचना सेवा"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ट्वाइलाइट समय बताने वाली सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"समय क्षेत्र का पता लगाने वाली सुविधा (ऑफ़लाइन होने पर)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"अब अपनी पूरी स्क्रीन या कुछ हिस्से को ज़ूम करके देख सकते हैं"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग में जाकर, इस सुविधा को चालू करें"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"खारिज करें"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index aebab8c..56f3978 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID dolaznog pozivatelja"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Sakrivanje ID-ja pozivatelja za odlazne pozive"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID povezane linije"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ograničenje ID-a povezane linije"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Preusmjeravanje poziva"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Usluga Obavijesti senzora"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sad možete povećati dio zaslona ili cijeli zaslon"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index efdf842..96997c0 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Beérkező hívóazonosító"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Kimenő hívásazonosító elrejtve"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Összekapcsolt sorazonosító"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Összekapcsolt sorazonosító korlátozása"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Hívásátirányítás"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Szenzoros értesítési szolgáltatás"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ezután nagyíthatja a képernyőt vagy egy részét"</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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 29803b8..996454a 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Մուտքային զանգողի ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Թաքցնե՞լ զանգողի ID-ն"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Կապված տողի ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Կապված տողի ID-ի սահմանափակում"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Զանգի վերահասցեավորում"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Տվիչների ծանուցումների մշակման ծառայություն"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Մթնշաղի սկիզբը որոշող ծառայություն"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Ժամային գոտու դետեկտոր (աշխատում է առանց ինտերնետի)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Այժմ կարող եք խոշորացնել ամբողջ էկրանը կամ դրա մի մասը"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Միացնել կարգավորումներում"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Փակել"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 510621b..bb91a6c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Nomor Penelepon Masuk"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Menyembunyikan ID Penelepon untuk Panggilan Keluar"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID Saluran yang Tersambung"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Batasan ID Saluran yang Tersambung"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Penerusan panggilan"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Layanan Notifikasi Sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Anda bisa memperbesar sebagian atau seluruh layar"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktifkan di Setelan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Tutup"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 802feeeb..ec11ad2 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Númerabirting innhringinga"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Fela númerabirtingu úthringinga"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Auðkenni tengdrar línu"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Auðkennistakmörkun tengdrar línu"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Símtalsflutningur"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Tilkynningaþjónusta nema"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nú geturðu stækkað allan skjáinn eða hluta hans"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Kveikja á í stillingum"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hunsa"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2c01776..df35881 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID chiamante in entrata"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Nascondi ID chiamante in uscita"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID linea connessa"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Limitazione ID linea connessa"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Deviazione chiamate"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Servizio di notifica dei sensori"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Puoi ingrandire lo schermo in parte o per intero"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Attiva nelle Impostazioni"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8cff250..f80750a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"זיהוי מתקשר של שיחה נכנסת"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"הסתרת זיהוי מתקשר בשיחה יוצאת"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"מזהה של קו מחובר"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"הגבלה של מזהה קו מחובר"</string>
     <string name="CfMmi" msgid="8390012691099787178">"העברת שיחות"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"שירות להתראות מחיישנים"</string>
     <string name="twilight_service" msgid="8964898045693187224">"שירות דמדומים"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"מזהה אזור זמן (ללא צורך בקישוריות)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"עכשיו אפשר להגדיל את המסך או חלקים ממנו"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"הפעלה בהגדרות"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"סגירה"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index cf493c0..04a0058 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"着信時の発信者番号"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"発信者番号を非通知にする"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"接続回線ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"接続回線IDの制限"</string>
     <string name="CfMmi" msgid="8390012691099787178">"着信転送"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"センサー通知サービス"</string>
     <string name="twilight_service" msgid="8964898045693187224">"トワイライト サービス"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time Zone Detector(未接続)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"画面の一部または全体を拡大できるようになりました"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"[設定] で ON にする"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"閉じる"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 9de08bc..6a128ab 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"შემომავალი ზარის აბონენტის ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"გამავალი აბონენტის ID-ის დამალვა"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"დაუკავშირდა Line ID-ს"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"დაუკავშირდა Line ID Restriction-ს"</string>
     <string name="CfMmi" msgid="8390012691099787178">"ზარის გადამისამართება"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"სენსორის შეტყობინების სერვისი"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight სერვისი"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"სასაათო სარტყლის დეტექტორი (კავშირის გარეშე)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ახლა შეგიძლიათ, გაადიდოთ ეკრანი ან მისი ნაწილი"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ჩართვა პარამეტრებში"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"უარყოფა"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index f38be01..8000fc4 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI (Халықаралық мобильдік құрылғы анықтағышы)"</string>
     <string name="meid" msgid="3291227361605924674">"MEID (ұялы құрылғы анықтағыш)"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Келген қоңырау шалушының жеке анықтағышы"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Шығыс қоңыраулары үшін қоңырау шалушының идентификаторын жасыру"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Қосылған желі идентификаторы"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Қосылған желі идентификаторын шектеу"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Қоңырауды басқа нөмірге бағыттау"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Датчик хабарландыруы қызметі"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight қызметі"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Уақыт белдеуін анықтағыш (қосылу мүмкіндігі жоқ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Енді экранның бір бөлігін не барлығын ұлғайта аласыз."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Параметрлер бөлімінен қосу"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Қабылдамау"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 2a70449..e6a2fc6 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"លេខ​សម្គាល់​អ្នក​ហៅ​​ចូល​"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"លាក់​អត្តសញ្ញាណ​អ្នកហៅ​ទូរសព្ទចេញ"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"បាន​ភ្ជាប់​លេខ​សម្គាល់​បន្ទាត់"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"បាន​ភ្ជាប់​ការ​ដាក់កម្រិត​លេខ​សម្គាល់​បន្ទាត់"</string>
     <string name="CfMmi" msgid="8390012691099787178">"បញ្ជូន​ការ​ហៅ​បន្ត"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"សេវាកម្ម​ជូនដំណឹង​ឧបករណ៍​ចាប់សញ្ញា"</string>
     <string name="twilight_service" msgid="8964898045693187224">"សេវាកម្ម​ព្រលប់"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ឧបករណ៍សម្គាល់​ល្វែងម៉ោង (គ្មានការតភ្ជាប់ទេ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ឥឡូវនេះ អ្នកអាចពង្រីកផ្នែកខ្លះ ឬទាំងអស់នៃអេក្រង់របស់អ្នក"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"បើកនៅក្នុងការកំណត់"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ច្រានចោល"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index b158306..f2d91f2 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ಒಳಬರುವ ಕರೆಮಾಡುವವರ ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"ಹೊರಹೋಗುವ ಕರೆಮಾಡುವವರ ID ಅನ್ನು ಮರೆಮಾಡಿ"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ಲೈನ್ ID ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"ಲೈನ್ ID ನಿರ್ಬಂಧನೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"ಕರೆಯ ರವಾನೆ"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"ಸೆನ್ಸರ್ ಅಧಿಸೂಚನೆ ಸೇವೆ"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ಟ್ವಿಲೈಟ್ ಸೇವೆ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ಸಮಯವಲಯ  ಡಿಟೆಕ್ಟರ್ (ಯಾವುದೇ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆ ಇಲ್ಲ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ಈಗ ಕೆಲವು ಅಥವಾ ಎಲ್ಲಾ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಹಿಗ್ಗಿಸಬಹುದು"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಆನ್ ಮಾಡಿ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ವಜಾಗೊಳಿಸಿ"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fd81606b..ea5de596 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"발신자 번호"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"발신 번호 숨김"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"환승편 ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"환승편 ID 제한"</string>
     <string name="CfMmi" msgid="8390012691099787178">"착신전환"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"센서 알림 서비스"</string>
     <string name="twilight_service" msgid="8964898045693187224">"새벽 서비스"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"시간대 감지(연결되지 않음)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"이제 화면 일부 또는 전체를 확대할 수 있습니다."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"설정에서 사용 설정"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"닫기"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 612193c..5137a22 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Кирүүчү номурду аныктоо"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Чыгуучу чалууларда чалуучунун идентификаторун жашыруу"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Туташкан линия ID-си"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Туташкан линия ID-син Чектөө"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Башка номерге багыттоо"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Сенсордун билдирмелеринин кызматы"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight кызматы"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Убакыт алкагын аныктагыч (байланыш жок)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Эми толук экранды же анын бөлүгүн чоңойто аласыз"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Жөндөөлөрдөн күйгүзүү"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Жабуу"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 760d920..7de2a91 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ໝາຍເລກຜູ່ໂທເຂົ້າ"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"ເຊື່ອງໝາຍເລກຜູ້ໂທສຳລັບການໂທອອກ"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Line ID ທີ່​ເຊື່ອມ​ໂຍງ"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"​ຂໍ້​ຈຳ​ກັດ Line ID ທີ່​ເຊື່ອມ​ໂຍງ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"ການໂອນສາຍ"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"ບໍລິການການແຈ້ງເຕືອນເຊັນເຊີ"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ບໍລິການ Twilight"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ຕົວກວດຫາເຂດເວລາ (ບໍ່ມີການເຊື່ອມຕໍ່)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ຕອນນີ້ທ່ານສາມາດຂະຫຍາຍບາງສ່ວນ ຫຼື ທັງໝົດຂອງໜ້າຈໍໄດ້"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ເປີດໃຊ້ໃນການຕັ້ງຄ່າ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ປິດໄວ້"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index da18b18..155d4cfb 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Įeinančio skambintojo ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Slėpti siunčiamojo skambučio skambintojo ID"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Prijungtos eilutės ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Prijungtos eilutės ID apribojimas"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Skambučio peradresavimas"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Jutiklių pranešimų paslauga"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Dabar galite padidinti dalį ekrano ar jį visą"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Įjungti nustatymuose"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Atmesti"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 4fdd570f..cd88997 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Ienākošā zvana zvanītāja ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Zvanītāja ID slēpšana izejošajiem zvaniem"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Saistītās līnijas ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Saistītās līnijas ID ierobežojums"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Zvanu pāradresācija"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensoru paziņojumu pakalpojums"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Tagad varat palielināt ekrāna daļu vai visu ekrānu"</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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b18ce23..d8ecc54 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID на дојдовен повикувач"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Сокривање излезен ID на повикувач"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID на поврзана линија"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Забрана на ID на поврзана линија"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Проследување повик"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга за известување од сензорот"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Услуга за самрак"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Откривач на временска зона (не може да се поврзе)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Сега може се зголеми целиот екран или само дел"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Вклучи во „Поставки“"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Отфрли"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index d21ab5a..f7a3161 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ഇൻകമിംഗ് വിളിച്ച നമ്പർ"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"ഔട്ട്ഗോയിംഗ് കോളർ ഐഡി മറയ്ക്കുക"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"കണക്‌റ്റുചെയ്‌തിരിക്കുന്ന ലൈൻ ഐഡി"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"കണക്‌റ്റുചെയ്‌തിരിക്കുന്ന ലൈൻ ഐഡി നിയന്ത്രണം"</string>
     <string name="CfMmi" msgid="8390012691099787178">"കോൾ ഫോർവേഡിംഗ്"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"സെൻസർ അറിയിപ്പ് സേവനം"</string>
     <string name="twilight_service" msgid="8964898045693187224">"സന്ധ്യാസമയത്തെ സേവനം"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"സമയമേഖല കണ്ടെത്താനുള്ള സംവിധാനം (കണക്റ്റിവിറ്റി ഇല്ല)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"സ്ക്രീനിന്റെ ഭാഗങ്ങളോ മുഴുവനുമോ മാഗ്നിഫൈ ചെയ്യാം"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ക്രമീകരണത്തിൽ ഓണാക്കുക"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 778a15b..cb3f00d 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Дуудлага хийгчийн ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Залгасан дуудлага хийгчийн ID-г нуух"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Холбогдсон шугамын ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Холбогдсон шугамын ID Хязгаарлалт"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Дуудлага дамжуулах"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Мэдрэгчийн мэдэгдлийн үйлчилгээ"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight үйлчилгээ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Цагийн бүс илрүүлэгч (Холболт байхгүй)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Та одоо зарим эсвэл бүх дэлгэцээ томруулж болно"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Тохиргоонд асаана уу"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Үл хэрэгсэх"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 37b2c11..4921f25 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -204,6 +204,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"सेन्सर सूचना सेवा"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ट्वायलाइट सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"टाइम झोन डिटेक्टर (कनेक्टिव्हिटी नाही)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2206,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"आता स्क्रीन अंशतः किंवा पूर्ण मॅग्निफाय करू शकता"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग्ज मध्ये सुरू करा"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"डिसमिस करा"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 686bbe6..557d64d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID Pemanggil Masuk"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Sembunyikan ID Pemanggil Keluar"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID Laluan yang disambungkan"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Sekatan ID Laluan yang disambungkan"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Pemajuan panggilan"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Perkhidmatan Pemberitahuan Penderia"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Besarkan sebahagian atau keseluruhan skrin anda"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Hidupkan dalam Tetapan"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Tolak"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f768d17..49387d8 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEIDနံပါတ်"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"အဝင်ခေါ်ဆိုမှုID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"အထွက် ခေါ်ဆိုသူ ID ကို ဝှက်ရန်"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"လိုင်း ID ချိတ်ဆက်သည်"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"လိုင်း ID ချိတ်ဆက်မှု ကန့်သတ်ချက်များ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"အာရုံခံကိရိယာ အကြောင်းကြားချက် ဝန်ဆောင်မှု"</string>
     <string name="twilight_service" msgid="8964898045693187224">"နေဝင်ဆည်းဆာ ဝန်ဆောင်မှု"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ဒေသစံတော်ချိန် ရှာဖွေစနစ် (ချိတ်ဆက်နိုင်မှု မလိုပါ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်း (သို့) တစ်ခုလုံး ချဲ့နိုင်ပါပြီ"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"\'ဆက်တင်များ\' တွင် ဖွင့်ရန်"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ပယ်ရန်"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c6831a8..2be1dab 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Inngående nummervisning"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Skjul Utgående anrops-ID"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Tilkoblet linje-ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Begrensning for tilkoblet linje-ID"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Viderekobling"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidssoneoppdagelse (ingen tilkobling)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nå kan du forstørre deler av eller hele skjermen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Slå på i innstillingene"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Avvis"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index ff0b00e..fac6dbc 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"आगमन कलर ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"बहिर्गमन कल गर्ने व्यक्तिको ID लुकाउनुहोस्"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"लाइन ID जोडियो"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"जोडिएको लाइन ID प्रतिबन्ध"</string>
     <string name="CfMmi" msgid="8390012691099787178">"कल अगाडि बढाउँदै"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"सेन्सरको सूचनासम्बन्धी सेवा"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ट्वाइलाइट सेवा"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"समय क्षेत्र पत्ता लगाउने सुविधा (नेटवर्क कनेक्सन नहुँदा)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"तपाईं अब स्क्रिनको केही वा सबै भाग जुम इन गर्न सक्नुहुन्छ"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिङमा गई यो सुविधा अन गर्नुहोस्"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"हटाउनुहोस्"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3b69609..c8621a1 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Inkomende beller-ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Uitgaande beller-ID verbergen"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID van verbonden lijn"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Beperking voor ID van verbonden lijn"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Gesprek doorschakelen"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Service voor sensormeldingen"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Je kunt je scherm nu (gedeeltelijk) vergroten"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Inschakelen in Instellingen"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Sluiten"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4b55e2d..6e07d75 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ଇନକମିଙ୍ଗ କଲର୍ ଆଇଡି"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"ଆଉଟଗୋଇଂ କଲର୍ IDକୁ ଲୁଚାନ୍ତୁ"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ସଂଯୁକ୍ତ ଲାଇନ୍ ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"ସଂଯୁକ୍ତ ଲାଇନ୍ ID କଟକଣା"</string>
     <string name="CfMmi" msgid="8390012691099787178">"କଲ୍‌ ଫରୱାର୍ଡିଂ"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"ସେନ୍ସର୍ ନୋଟିଫିକେସନ୍ ସର୍ଭିସ୍"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ଟ୍ୱିଲାଇଟ୍ ସର୍ଭିସ୍"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ଟାଇମ୍‍ ଜୋନ୍‍ ଡିଟେକ୍ଟର୍‍ (କୌଣସି ସଂଯୋଗ ନାହିଁ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ଆପଣ ଏବେ ଆଂଶିକ ବା ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ ବଡ଼ କରିପାରିବେ"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ସେଟିଂସରେ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ଖାରଜ କରନ୍ତୁ"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 8fc507f..52e124c 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -204,6 +204,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"ਸੈਂਸਰ ਸੂਚਨਾ ਸੇਵਾ"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ਟਵੀਲਾਈਟ ਸੇਵਾ"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ਸਮਾਂ ਖੇਤਰ ਦਾ ਪਤਾ ਲਗਾਉਣ ਦੀ ਸੁਵਿਧਾ (ਕੋਈ ਕਨੈਕਟੀਵਿਟੀ ਨਹੀਂ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2206,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ਹੁਣ ਤੁਸੀਂ ਕੁਝ ਜਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰੋ"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ਖਾਰਜ ਕਰੋ"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8d669c4..3711cb7 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID rozmówcy przy połączeniach przychodzących"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ukryj ID rozmówcy przy rozmowie wychodzącej"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Identyfikator połączonej linii"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ograniczenie identyfikatora połączonej linii"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Przekierowanie połączeń"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Usługa powiadomień czujnika"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Możesz teraz powiększyć część lub całość ekranu"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Włącz w Ustawieniach"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odrzuć"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index bdcf7af..e9364c4 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Serviço de notificações do sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora você pode ampliar uma ou todas as suas telas"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e065e55..374ab95 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Serviço de notificações do sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Já pode ampliar o ecrã parcial ou totalmente."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Definições"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index bdcf7af..e9364c4 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Serviço de notificações do sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Agora você pode ampliar uma ou todas as suas telas"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 68dad1c..38f9854 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID apelant de primire"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ascundeți ID-ul apelantului"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID-ul liniei conectate"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restricționarea ID-ului liniei conectate"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Redirecționarea apelurilor"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Serviciu pentru notificări de la senzori"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Acum puteți mări o parte sau tot ecranul"</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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 03383f9..6408cce 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Идентификация вызывающего абонента"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Идентификация звонящего абонента"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Идентификатор подключенной линии"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ограничение идентификатора подключенной линии"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Переадресация вызовов"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Сервис для обработки уведомлений от датчиков"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Сервис для определения наступления сумерек"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Определитель часового пояса (работает без Интернета)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Теперь можно увеличивать весь экран или его часть."</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включить в настройках"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Закрыть"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index a56a5f8..a6d54f4 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"සංවේදක දැනුම් දීමේ සේවාව"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ඇඳිරි සේවාව"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"වේලා කලාප අනාවරකය (සම්බන්ධතාවක් නොමැත)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"ඔබට දැන් තිරයේ සමහර හෝ සියලු දේ විශාලනය කළ හැකිය"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"සැකසීම් තුළ ක්‍රියාත්මක කරන්න"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ඉවත ලන්න"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f8dfc26..a478083 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Prichádzajúca identifikácia volajúceho"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Skryť identifikáciu volajúcich pri odchádzajúcich hovoroch"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID pripojenej linky"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Obmedzenie ID pripojenej linky"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Presmerovanie hovorov"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Služba upozornení senzora"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Teraz môžete zväčšiť celú obrazovku alebo jej časť"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnúť v Nastaveniach"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Zavrieť"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 4a5c5da..b353f45 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID dohodnega klicatelja"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Skrivanje ID-ja odhodnega klicatelja"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID povezane linije"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Omejitev ID-ja povezane linije"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Preusmerjanje klicev"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Storitev obvestil tipal"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Zdaj lahko povečate del zaslona ali celotni zaslon"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vklopite v nastavitvah"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Opusti"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 8feea9c..86f191f 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID-ja e telefonuesit hyrës"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Fshih ID-në e telefonuesit në dalje"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID-ja e linjës së lidhur"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Kufizimi i ID-së së linjës së lidhur"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Transferimi i telefonatave"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Shërbimi i njoftimeve të sensorit"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Tani mund t\'i zmadhosh një pjesë apo të gjithë ekranin tënd"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivizo te \"Cilësimet\""</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Hiq"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a430d56..594a2ee 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -58,8 +58,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Долазни ИД позиваоца"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Сакријте ИД одлазног позиваоца"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ИД повезане линије"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Ограничење ИД-а повезане линије"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Преусмеравање позива"</string>
@@ -206,6 +205,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга обавештења сензора"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Услуга Сумрак"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Детектор временске зоне (нема интернет везе)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2238,4 +2239,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Можете да увећате део екрана или цео екран"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Укључите у Подешавањима"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Одбаци"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 186a78a..d87ae37 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI-kod"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Nummerpresentatör för inkommande samtal"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Dölj nummerpresentatör för utgående samtal"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Visning av uppkopplat nummer"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Blockera visning av uppkopplat nummer"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Vidarekoppla samtal"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensor Notification Service"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Tidszondetektering (ingen anslutning)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Nu kan du förstora delar av eller hela skärmen"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivera i inställningarna"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Stäng"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cf9496d..93f0ed9 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Kitambulisho cha Mpigaji wa Simu Inayoingia"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Ficha Kitambulisho Chako Unapopiga Simu"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Kitambulisho cha Mstari Uliounganishwa"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Kizuizi cha Kitambulisho cha Mstari Uliounganishwa"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Kusambaza simu"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Huduma ya Arifa ya Kitambuzi"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Sasa unaweza kukuza sehemu ya au skrini yako yote"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Washa katika Mipangilio"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Ondoa"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index f3e5f91..53052d7 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"உள்வரும் அழைப்பாளர் ஐடி"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"வெளிச்செல்லும் அழைப்பாளர் ஐடியை மறைத்தல்"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"இணைக்கப்பட்ட லைன் ஐடி"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"இணைக்கப்பட்ட லைன் ஐடியை வரம்பிடல்"</string>
     <string name="CfMmi" msgid="8390012691099787178">"அழைப்பு திருப்பிவிடுதல்"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"சென்சார் அறிவிப்புச் சேவை"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight சேவை"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"நேர மண்டல டிடெக்டர் (இணைப்பு இல்லை)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"திரை முழுவதையுமோ ஒரு பகுதியையோ பெரிதாக்கலாம்"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"அமைப்புகளில் ஆன் செய்க"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"மூடுக"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 29d90bd..2de91ba 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ఇన్‌కమింగ్ కాలర్ ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"అవుట్‌గోయింగ్ కాలర్ IDని దాచండి"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"కనెక్ట్ చేయబడిన పంక్తి ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"కనెక్ట్ చేయబడిన పంక్తి ID నియంత్రణ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"కాల్ ఫార్వర్డింగ్"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"సెన్సార్ నోటిఫికేషన్ సర్వీస్"</string>
     <string name="twilight_service" msgid="8964898045693187224">"ట్విలైట్ సర్వీస్"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"టైమ్ జోన్ డిటెక్టర్ (కనెక్టివిటీ లేదు)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"స్క్రీన్ మొత్తం లేదా కొంత భాగాన్ని జూమ్ చేయవచ్చు"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"సెట్టింగ్‌లలో ఆన్ చేయండి"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"విస్మరించు"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 01ffd62..aa3331a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"หมายเลขผู้โทรเข้า"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"ซ่อนหมายเลขผู้โทรออก"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"รหัสสายที่เชื่อมต่อ"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"ข้อจำกัดรหัสสายที่เชื่อมต่อ"</string>
     <string name="CfMmi" msgid="8390012691099787178">"การโอนสาย"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"บริการแจ้งเตือนเกี่ยวกับเซ็นเซอร์"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight Service"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ตัวตรวจจับเขตเวลา (ไม่มีการเชื่อมต่อ)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"คุณสามารถขยายหน้าจอบางส่วนหรือทั้งหมดได้แล้วตอนนี้"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"เปิดในการตั้งค่า"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"ปิด"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 40968eb..d3a1fe7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Papasok na Caller ID"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Itago ang Outgoing Caller ID"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Connected Line ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Paghihigpit sa Connected Line ID"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Pagpapasa ng tawag"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Serbisyo ng Notification ng Sensor"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Mama-magnify na ang bahagi o kabuuan ng screen mo"</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>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 342ff20..26108fb 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Gelen Çağrı Kimliği"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Giden Arama Arayan Kimliğini Gizle"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Bağlanılan Hat Kimliği"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Bağlanılan Hat Kimliğini Kısıtlama"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Çağrı yönlendirme"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensör Bildirim Hizmeti"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <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="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlar\'da aç"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Kapat"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index cf2c6f1..abb1b7d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -59,8 +59,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"Вхідн. ід. абонента"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Приховати ідентифікатор абонента для вихідних викликів"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"Ідентифікатор під’єднаної лінії"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Обмеження ідентифікатора під’єднаної лінії"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Переадресація виклику"</string>
@@ -208,6 +207,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Сервіс \"Сповіщення датчика\""</string>
     <string name="twilight_service" msgid="8964898045693187224">"Сервіс \"Сутінки\""</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Визначення часового поясу (без Інтернету)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2272,4 +2273,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Тепер можна збільшити весь екран або його частину"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Увімкнути в налаштуваннях"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Закрити"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index b66a80e..ae7b5a5 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -204,6 +204,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"سینسر نوٹیفکیشن سروس"</string>
     <string name="twilight_service" msgid="8964898045693187224">"شفقی سروس"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"ٹائم زون ڈیٹیکٹر (کوئی کنیکٹوٹی نہیں ہے)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2206,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"اب آپ اپنی تمام یا کچھ اسکرین کو بڑا کر سکتے ہیں"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ترتیبات میں آن کریں"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"برخاست کریں"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 2371950..e72114a 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -203,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Sensorli bildirishnoma xizmati"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2203,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Ekranni toʻliq yoki qisman kattalashtirish mumkin"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Sozlamalar orqali yoqish"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Yopish"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 0af241e..b3fdcfc 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -204,6 +204,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Dịch vụ Thông báo của cảm biến"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2206,12 @@
     <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="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bật trong phần Cài đặt"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Đóng"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4503305..347ad56 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"来电显示"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"外拨时隐藏本机号码"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"连接的线路ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"连接的线路ID限制"</string>
     <string name="CfMmi" msgid="8390012691099787178">"来电转接"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"传感器通知服务"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight 服务"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"时区检测器(无网络连接)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"您现在可以放大屏幕上的部分或所有内容"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 92b007c..79ce664 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"來電顯示"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"撥出時隱藏「來電顯示」資料"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"連接線識別功能"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"連接線識別限制"</string>
     <string name="CfMmi" msgid="8390012691099787178">"來電轉駁"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"感應器通知服務"</string>
     <string name="twilight_service" msgid="8964898045693187224">"暮光服務"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"時區偵測器 (沒有連線)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"您現在可以放大部分或整個畫面"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index df2d5ea..15a1201 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"來電顯示"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"撥出時隱藏「來電顯示」資訊"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"連接的線路 ID"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"連接的線路 ID 限制"</string>
     <string name="CfMmi" msgid="8390012691099787178">"來電轉接"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"感應器通知服務"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Twilight 服務"</string>
     <string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"時區偵測器 (不必連上網路)"</string>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"你可以放大局部或整個畫面"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3f2d547..b18afe7 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -57,8 +57,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"I-ID Yocingo Olungenayo"</string>
-    <!-- no translation found for ClirMmi (6752346475055446417) -->
-    <skip />
+    <string name="ClirMmi" msgid="6752346475055446417">"Fihla Ubunikazi Bekholi Ephumayo"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"I-ID yomugqa exhumekile"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"I-ID yomugqa oxhumekile ikhawulelwe"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Ukudlulisa ikholi"</string>
@@ -204,6 +203,8 @@
     <string name="sensor_notification_service" msgid="7474531979178682676">"Isevisi Yesaziso Senzwa"</string>
     <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>
+    <!-- no translation found for gnss_time_update_service (9039489496037616095) -->
+    <skip />
     <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>
@@ -2204,4 +2205,12 @@
     <string name="window_magnification_prompt_content" msgid="4166711383253283838">"Manje usungakwazi ukukhulisa esinye noma sonke isikrini sakho"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vula Kumasethingi"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Cashisa"</string>
+    <!-- no translation found for sensor_privacy_start_use_mic_notification_content (8063355861118105607) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_camera_notification_content (4738005643315863736) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7921147002346108119) -->
+    <skip />
+    <!-- no translation found for sensor_privacy_notification_channel_label (936036783155261349) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index c3cd80b..0ef60c4 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -17,6 +17,7 @@
 -->
 <resources>
     <dimen name="car_large_avatar_size">96dp</dimen>
+    <dimen name="car_large_avatar_badge_size">32dp</dimen>
     <!-- Application Bar -->
     <dimen name="car_app_bar_height">80dp</dimen>
     <!-- Margin -->
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
index d8ed805..daae957 100644
--- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
@@ -76,6 +76,12 @@
     private static final long DUMPSTATE_STARTUP_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
     private static final long UIAUTOMATOR_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
 
+
+    // A small timeout used when waiting for the result of a BugreportCallback to be received.
+    // This value must be at least 1000ms since there is an intentional delay in
+    // BugreportManagerServiceImpl in the error case.
+    private static final long CALLBACK_RESULT_TIMEOUT_MS = 1500;
+
     // Sent by Shell when its bugreport finishes (contains final bugreport/screenshot file name
     // associated with the bugreport).
     private static final String INTENT_BUGREPORT_FINISHED =
@@ -185,7 +191,7 @@
         ParcelFileDescriptor bugreportFd2 = parcelFd(bugreportFile2);
         ParcelFileDescriptor screenshotFd2 = parcelFd(screenshotFile2);
         mBrm.startBugreport(bugreportFd2, screenshotFd2, wifi(), mExecutor, callback2);
-        Thread.sleep(500 /* .5s */);
+        Thread.sleep(CALLBACK_RESULT_TIMEOUT_MS);
 
         // Verify #2 encounters an error.
         assertThat(callback2.getErrorCode()).isEqualTo(
@@ -194,7 +200,7 @@
 
         // Cancel #1 so we can move on to the next test.
         mBrm.cancelBugreport();
-        Thread.sleep(500 /* .5s */);
+        waitTillDoneOrTimeout(callback);
         assertThat(callback.isDone()).isTrue();
         assertFdsAreClosed(mBugreportFd, mScreenshotFd);
     }
@@ -220,7 +226,7 @@
         // Try again, with DUMP permission.
         getPermissions();
         mBrm.cancelBugreport();
-        Thread.sleep(500 /* .5s */);
+        waitTillDoneOrTimeout(callback);
         assertThat(callback.isDone()).isTrue();
         assertFdsAreClosed(mBugreportFd, mScreenshotFd);
     }
diff --git a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
index 0f17d27..6be9306 100644
--- a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
@@ -254,7 +254,7 @@
         assertEquals("19–22 de ene. de 2009",
                 formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY,
                         FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-        assertEquals("lun., 19 de ene. – jue., 22 de ene. de 2009",
+        assertEquals("lun, 19 de ene. – jue, 22 de ene. de 2009",
                 formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY,
                         FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
         assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009",
@@ -265,7 +265,7 @@
         assertEquals("19 de ene. – 22 de abr. 2009",
                 formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH,
                         FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-        assertEquals("lun., 19 de ene. – mié., 22 de abr. de 2009",
+        assertEquals("lun, 19 de ene. – mié, 22 de abr. de 2009",
                 formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH,
                         FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
         assertEquals("enero–abril de 2009",
@@ -286,9 +286,9 @@
 
         assertEquals("19–22 de enero de 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, 0));
-        assertEquals("19–22 ene. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY,
+        assertEquals("19–22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY,
                 FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-        assertEquals("lun., 19 ene. – jue., 22 ene. 2009",
+        assertEquals("lun, 19 ene – jue, 22 ene 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY,
                         FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
         assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009",
@@ -296,19 +296,19 @@
 
         assertEquals("19 de enero–22 de abril de 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0));
-        assertEquals("19 ene. – 22 abr. 2009",
+        assertEquals("19 ene – 22 abr 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH,
                         FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-        assertEquals("lun., 19 ene. – mié., 22 abr. 2009",
+        assertEquals("lun, 19 ene – mié, 22 abr 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH,
                         FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
         assertEquals("enero–abril de 2009",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
 
-        assertEquals("19 ene. 2009 – 9 feb. 2012",
+        assertEquals("19 ene 2009 – 9 feb 2012",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR,
                         FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-        assertEquals("ene. 2009 – feb. 2012",
+        assertEquals("ene 2009 – feb 2012",
                 formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR,
                         FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
         assertEquals("19 de enero de 2009–9 de febrero de 2012",
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index 068d047..5612833 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -212,7 +212,7 @@
 
         // Make sure it works on different locales.
         setLocale(new Locale("ru", "RU"));
-        assertEquals("1 мин.", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+        assertEquals("1 мин", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                 mContext, 1 * SECOND));
     }
 
diff --git a/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java
index 4b3b573..b342516 100644
--- a/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java
@@ -755,8 +755,8 @@
         final Locale locale = new Locale("fr");
         android.icu.text.RelativeDateTimeFormatter icuFormatter =
                 android.icu.text.RelativeDateTimeFormatter.getInstance(locale);
-        assertEquals("D à T", icuFormatter.combineDateAndTime("D", "T"));
+        assertEquals("D, T", icuFormatter.combineDateAndTime("D", "T"));
         // Ensure single quote ' and curly braces {} are not interpreted in input values.
-        assertEquals("D'x' à T{0}", icuFormatter.combineDateAndTime("D'x'", "T{0}"));
+        assertEquals("D'x', T{0}", icuFormatter.combineDateAndTime("D'x'", "T{0}"));
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index dc33253..143e07a 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -46,6 +46,7 @@
         BstatsCpuTimesValidationTest.class,
         CameraPowerCalculatorTest.class,
         FlashlightPowerCalculatorTest.class,
+        GnssPowerCalculatorTest.class,
         IdlePowerCalculatorTest.class,
         KernelCpuProcStringReaderTest.class,
         KernelCpuUidActiveTimeReaderTest.class,
@@ -62,6 +63,7 @@
         PowerCalculatorTest.class,
         PowerProfileTest.class,
         ScreenPowerCalculatorTest.class,
+        SensorPowerCalculatorTest.class,
         SystemServicePowerCalculatorTest.class,
         VideoPowerCalculatorTest.class,
 
diff --git a/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java
new file mode 100644
index 0000000..bd7f1e2
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.BatteryConsumer;
+import android.os.Process;
+import android.os.UidBatteryConsumer;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GnssPowerCalculatorTest {
+    private static final double PRECISION = 0.00001;
+
+    private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
+
+    @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});
+
+    @Test
+    public void testTimerBasedModel() {
+        BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID);
+        uidStats.noteStartGps(1000);
+        uidStats.noteStopGps(2000);
+
+        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(0.1);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java
new file mode 100644
index 0000000..b50435b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.input.InputSensorInfo;
+import android.os.BatteryConsumer;
+import android.os.Process;
+import android.os.UidBatteryConsumer;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SensorPowerCalculatorTest {
+    private static final double PRECISION = 0.00001;
+
+    private static final int SENSOR_HANDLE_1 = 1;
+    private static final int SENSOR_HANDLE_2 = 2;
+
+    private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
+
+    @Rule
+    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
+
+    @Test
+    public void testTimerBasedModel() {
+        Sensor sensor1 = createSensor(SENSOR_HANDLE_1, Sensor.TYPE_AMBIENT_TEMPERATURE, 360);
+        Sensor sensor2 = createSensor(SENSOR_HANDLE_2, Sensor.TYPE_STEP_COUNTER, 720);
+
+        SensorManager sensorManager = mock(SensorManager.class);
+        when(sensorManager.getSensorList(Sensor.TYPE_ALL))
+                .thenReturn(List.of(sensor1, sensor2));
+
+        BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID);
+        uidStats.noteStartSensor(SENSOR_HANDLE_1, 1000);
+        uidStats.noteStopSensor(SENSOR_HANDLE_1, 2000);
+        uidStats.noteStartSensor(SENSOR_HANDLE_2, 3000);
+        uidStats.noteStopSensor(SENSOR_HANDLE_2, 5000);
+
+        SensorPowerCalculator calculator = new SensorPowerCalculator(sensorManager);
+
+        mStatsRule.apply(calculator);
+
+        UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
+        assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SENSORS))
+                .isEqualTo(3000);
+        assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS))
+                .isWithin(PRECISION).of(0.5);
+    }
+
+    private Sensor createSensor(int handle, int type, double power) {
+        return new Sensor(new InputSensorInfo("name", "vendor", 0 /* version */,
+                handle, type, 100.0f /*maxRange */, 0.02f /* resolution */,
+                (float) power, 1000 /* minDelay */, 0 /* fifoReservedEventCount */,
+                0 /* fifoMaxEventCount */, "" /* stringType */, "" /* requiredPermission */,
+                0 /* maxDelay */, 0 /* flags */, 0 /* id */));
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
index e0884e3..9394dec 100644
--- a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
+++ b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
@@ -42,14 +42,14 @@
         AngleOfArrivalMeasurement.Builder builder = new AngleOfArrivalMeasurement.Builder();
         tryBuild(builder, false);
 
-        builder.setAltitudeAngleMeasurement(altitude);
+        builder.setAltitude(altitude);
         tryBuild(builder, false);
 
-        builder.setAzimuthAngleMeasurement(azimuth);
+        builder.setAzimuth(azimuth);
         AngleOfArrivalMeasurement measurement = tryBuild(builder, true);
 
-        assertEquals(azimuth, measurement.getAzimuthAngleMeasurement());
-        assertEquals(altitude, measurement.getAltitudeAngleMeasurement());
+        assertEquals(azimuth, measurement.getAzimuth());
+        assertEquals(altitude, measurement.getAltitude());
     }
 
     private AngleMeasurement getAngleMeasurement(double radian, double error, double confidence) {
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
index b4b2e30..8e7f7c56 100644
--- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -42,8 +42,8 @@
 
     public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
         return new AngleOfArrivalMeasurement.Builder()
-                .setAltitudeAngleMeasurement(getAngleMeasurement())
-                .setAzimuthAngleMeasurement(getAngleMeasurement())
+                .setAltitude(getAngleMeasurement())
+                .setAzimuth(getAngleMeasurement())
                 .build();
     }
 
diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp
index 7f20b3b..41a6fea 100644
--- a/data/etc/car/Android.bp
+++ b/data/etc/car/Android.bp
@@ -122,13 +122,6 @@
 }
 
 prebuilt_etc {
-    name: "allowed_privapp_com.android.car.companiondevicesupport",
-    sub_dir: "permissions",
-    src: "com.android.car.companiondevicesupport.xml",
-    filename_from_src: true,
-}
-
-prebuilt_etc {
     name: "allowed_privapp_com.google.android.car.kitchensink",
     sub_dir: "permissions",
     src: "com.google.android.car.kitchensink.xml",
diff --git a/data/etc/car/com.android.car.companiondevicesupport.xml b/data/etc/car/com.android.car.companiondevicesupport.xml
deleted file mode 100644
index 2067bab..0000000
--- a/data/etc/car/com.android.car.companiondevicesupport.xml
+++ /dev/null
@@ -1,24 +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
-  -->
-<permissions>
-    <privapp-permissions package="com.android.car.companiondevicesupport">
-      <permission name="android.permission.INTERACT_ACROSS_USERS"/>
-      <permission name="android.permission.MANAGE_USERS"/>
-      <permission name="android.permission.PROVIDE_TRUST_AGENT"/>
-      <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
-    </privapp-permissions>
-</permissions>
diff --git a/data/etc/com.android.cellbroadcastreceiver.xml b/data/etc/com.android.cellbroadcastreceiver.xml
index ef49bfa..01a28a8 100644
--- a/data/etc/com.android.cellbroadcastreceiver.xml
+++ b/data/etc/com.android.cellbroadcastreceiver.xml
@@ -16,6 +16,7 @@
   -->
 <permissions>
     <privapp-permissions package="com.android.cellbroadcastreceiver">
+        <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 06f1dae..3d964fb 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -67,5 +67,8 @@
         <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
         <permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
         <permission name="android.permission.CAMERA_OPEN_CLOSE_LISTENER" />
+        <permission name="android.permission.READ_WIFI_CREDENTIAL" />
+        <permission name="android.permission.USE_BACKGROUND_BLUR" />
+        <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml
index 6255584..ff8d96d 100644
--- a/data/etc/preinstalled-packages-platform.xml
+++ b/data/etc/preinstalled-packages-platform.xml
@@ -17,9 +17,8 @@
 <!--
 This XML file declares which system packages should be initially installed for new users based on
 their user type. All system packages on the device should ideally have an entry in an xml file
-(keyed by its manifest name), except auto-generated rro packages. Auto-generated RRO packages 
-(package name ends with ".auto_generated_rro_product__" or ".auto_generated_rro_vendor__")
-will be installed for new users according to corresponding overlay target packages.
+(keyed by its manifest name), except for static overlays which are instead treated automatically
+according to the entry for their corresponding overlay target package.
 
 Base user-types (every user will be at least one of these types) are:
   SYSTEM    (user 0)
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index c3d822c..03f8918 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -46,6 +46,7 @@
     </privapp-permissions>
 
     <privapp-permissions package="com.android.cellbroadcastreceiver.module">
+        <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
@@ -74,6 +75,7 @@
     <privapp-permissions package="com.android.location.fused">
         <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
         <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.managedprovisioning">
@@ -95,6 +97,7 @@
         <permission name="android.permission.SHUTDOWN"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
+        <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.mms.service">
@@ -464,6 +467,7 @@
         <permission name="android.permission.BIND_CARRIER_SERVICES"/>
         <!-- Permission required for CTS test - CallLogTest -->
         <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+        <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 54167b4..6aa50db 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -50,9 +50,11 @@
     private static final String DEFAULT_FAMILY = "sans-serif";
 
     private static final String FONTS_XML = "/system/etc/fonts.xml";
-    private static final String SYSTEM_FONT_DIR = "/system/fonts/";
+    /** @hide */
+    public static final String SYSTEM_FONT_DIR = "/system/fonts/";
     private static final String OEM_XML = "/product/etc/fonts_customization.xml";
-    private static final String OEM_FONT_DIR = "/product/fonts/";
+    /** @hide */
+    public static final String OEM_FONT_DIR = "/product/fonts/";
 
     private SystemFonts() {}  // Do not instansiate.
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
index 7aedc1b..4b3fc81 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
@@ -74,7 +74,13 @@
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
         final Point positionInParent = taskInfo.positionInParent;
-        mSyncQueue.runInSync(t -> t.setPosition(leash, positionInParent.x, positionInParent.y));
+        mSyncQueue.runInSync(t -> {
+            // Reset several properties back. For instance, when an Activity enters PiP with
+            // multiple activities in the same task, a new task will be created from that Activity
+            // and we want reset the leash of the original task.
+            t.setPosition(leash, positionInParent.x, positionInParent.y);
+            t.setWindowCrop(leash, null);
+        });
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 32c6e36..1971ca9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -131,7 +131,11 @@
      */
     public void setRenderedBubble(BubbleViewProvider bubble) {
         mBubble = bubble;
-        showBadge();
+        if (mDotSuppressionFlags.contains(SuppressionFlag.BEHIND_STACK)) {
+            hideBadge();
+        } else {
+            showBadge();
+        }
         mDotColor = bubble.getDotColor();
         drawDot(bubble.getDotPath());
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 0f81d7e..fac3686 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -647,10 +647,12 @@
                 } else {
                     // Fling the stack to the edge, and save whether or not it's going to end up on
                     // the left side of the screen.
+                    final boolean oldOnLeft = mStackOnLeftOrWillBe;
                     mStackOnLeftOrWillBe =
                             mStackAnimationController.flingStackThenSpringToEdge(
                                     viewInitialX + dx, velX, velY) <= 0;
-                    updateBubbleIcons();
+                    final boolean updateForCollapsedStack = oldOnLeft != mStackOnLeftOrWillBe;
+                    updateBadgesAndZOrder(updateForCollapsedStack);
                     logBubbleEvent(null /* no bubble associated with bubble stack move */,
                             FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED);
                 }
@@ -1481,7 +1483,7 @@
         };
         if (mIsExpanded) {
             reorder.run();
-            updateBubbleIcons();
+            updateBadgesAndZOrder(false /* setBadgeForCollapsedStack */);
         } else {
             List<View> bubbleViews = bubbles.stream()
                     .map(b -> b.getIconView()).collect(Collectors.toList());
@@ -2616,27 +2618,28 @@
         }
 
         mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
-        updateBubbleIcons();
+        updateBadgesAndZOrder(false /* setBadgeForCollapsedStack */);
     }
 
     /**
      * Sets the appropriate Z-order, badge, and dot position for each bubble in the stack.
      * Animate dot and badge changes.
      */
-    private void updateBubbleIcons() {
+    private void updateBadgesAndZOrder(boolean setBadgeForCollapsedStack) {
         int bubbleCount = getBubbleCount();
         for (int i = 0; i < bubbleCount; i++) {
             BadgedImageView bv = (BadgedImageView) mBubbleContainer.getChildAt(i);
             bv.setZ((mMaxBubbles * mBubbleElevation) - i);
-
             if (mIsExpanded) {
                 // If we're not displaying vertically, we always show the badge on the left.
                 boolean onLeft = mPositioner.showBubblesVertically() && !mStackOnLeftOrWillBe;
                 bv.showDotAndBadge(onLeft);
-            } else if (i == 0) {
-                bv.showDotAndBadge(!mStackOnLeftOrWillBe);
-            } else {
-                bv.hideDotAndBadge(!mStackOnLeftOrWillBe);
+            } else if (setBadgeForCollapsedStack) {
+                if (i == 0) {
+                    bv.showDotAndBadge(!mStackOnLeftOrWillBe);
+                } else {
+                    bv.hideDotAndBadge(!mStackOnLeftOrWillBe);
+                }
             }
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
index 96398be..e1f831e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
@@ -64,10 +64,10 @@
 
     /** Values to use for animating bubbles in. */
     private static final float ANIMATE_IN_STIFFNESS = 1000f;
-    private static final int ANIMATE_IN_START_DELAY = 25;
 
     /** Values to use for animating updated bubble to top of stack. */
-    private static final float BUBBLE_SWAP_SCALE = 0.8f;
+    private static final float NEW_BUBBLE_START_SCALE = 0.5f;
+    private static final float NEW_BUBBLE_START_Y = 100f;
     private static final long BUBBLE_SWAP_DURATION = 300L;
 
     /**
@@ -779,48 +779,58 @@
     }
 
     public void animateReorder(List<View> bubbleViews, Runnable after) {
+        // After the bubble going to index 0 springs above stack, update all icons
+        // at the same time, to avoid visibly changing bubble order before the animation completes.
+        Runnable updateAllIcons = () -> {
+            for (int newIndex = 0; newIndex < bubbleViews.size(); newIndex++) {
+                View view = bubbleViews.get(newIndex);
+                updateBadgesAndZOrder(view, newIndex);
+            }
+        };
+
         for (int newIndex = 0; newIndex < bubbleViews.size(); newIndex++) {
             View view = bubbleViews.get(newIndex);
             final int oldIndex = mLayout.indexOfChild(view);
-            animateSwap(view, oldIndex, newIndex, after);
+            animateSwap(view, oldIndex, newIndex, updateAllIcons, after);
         }
     }
 
-    private void animateSwap(View view, int oldIndex, int newIndex, Runnable finishReorder) {
-        final float newY = getStackPosition().y + newIndex * mSwapAnimationOffset;
-        final float swapY = newIndex == 0
-                ? newY - mSwapAnimationOffset  // Above top of stack
-                : newY + mSwapAnimationOffset;  // Below where bubble will be
-        final ViewPropertyAnimator animator = view.animate()
-                .scaleX(BUBBLE_SWAP_SCALE)
-                .scaleY(BUBBLE_SWAP_SCALE)
-                .translationY(swapY)
+    private void animateSwap(View view, int oldIndex, int newIndex,
+            Runnable updateAllIcons, Runnable finishReorder) {
+        if (newIndex == oldIndex) {
+            // Add new bubble to index 0; move existing bubbles down
+            updateBadgesAndZOrder(view, newIndex);
+            if (newIndex == 0) {
+                animateInBubble(view, newIndex);
+            } else {
+                moveToFinalIndex(view, newIndex, finishReorder);
+            }
+        } else {
+            // Reorder existing bubbles
+            if (newIndex == 0) {
+                animateToFrontThenUpdateIcons(view, updateAllIcons, finishReorder);
+            } else {
+                moveToFinalIndex(view, newIndex, finishReorder);
+            }
+        }
+    }
+
+    private void animateToFrontThenUpdateIcons(View v, Runnable updateAllIcons,
+            Runnable finishReorder) {
+        final ViewPropertyAnimator animator = v.animate()
+                .translationY(getStackPosition().y - mSwapAnimationOffset)
                 .setDuration(BUBBLE_SWAP_DURATION)
                 .withEndAction(() -> {
-                    finishSwapAnimation(view, oldIndex, newIndex, finishReorder);
+                    updateAllIcons.run();
+                    moveToFinalIndex(v, 0 /* index */, finishReorder);
                 });
-        view.setTag(R.id.reorder_animator_tag, animator);
+        v.setTag(R.id.reorder_animator_tag, animator);
     }
 
-    private void finishSwapAnimation(View view, int oldIndex, int newIndex,
+    private void moveToFinalIndex(View view, int newIndex,
             Runnable finishReorder) {
-
-        // At this point, swapping bubbles have the least overlap.
-        // Update z-index and badge visibility here for least jarring transition.
-        view.setZ((mMaxBubbles * mElevation) - newIndex);
-        BadgedImageView bv = (BadgedImageView) view;
-        if (oldIndex == 0 && newIndex > 0) {
-            bv.hideDotAndBadge(!isStackOnLeftSide());
-        } else if (oldIndex > 0 && newIndex == 0) {
-            bv.showDotAndBadge(!isStackOnLeftSide());
-        }
-
-        // Animate bubble back into stack, at new index and original size.
-        final float newY = getStackPosition().y + newIndex * mStackOffset;
         final ViewPropertyAnimator animator = view.animate()
-                .scaleX(1f)
-                .scaleY(1f)
-                .translationY(newY)
+                .translationY(getStackPosition().y + newIndex * mStackOffset)
                 .setDuration(BUBBLE_SWAP_DURATION)
                 .withEndAction(() -> {
                     view.setTag(R.id.reorder_animator_tag, null);
@@ -829,14 +839,20 @@
         view.setTag(R.id.reorder_animator_tag, animator);
     }
 
-    @Override
-    void onChildReordered(View child, int oldIndex, int newIndex) {
-        if (isStackPositionSet()) {
-            setStackPosition(mStackPosition);
+    private void updateBadgesAndZOrder(View v, int index) {
+        v.setZ((mMaxBubbles * mElevation) - index);
+        BadgedImageView bv = (BadgedImageView) v;
+        if (index == 0) {
+            bv.showDotAndBadge(!isStackOnLeftSide());
+        } else {
+            bv.hideDotAndBadge(!isStackOnLeftSide());
         }
     }
 
     @Override
+    void onChildReordered(View child, int oldIndex, int newIndex) {}
+
+    @Override
     void onActiveControllerForLayout(PhysicsAnimationLayout layout) {
         Resources res = layout.getResources();
         mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
@@ -943,35 +959,29 @@
     }
 
     /** Animates in the given bubble. */
-    private void animateInBubble(View child, int index) {
+    private void animateInBubble(View v, int index) {
         if (!isActiveController()) {
             return;
         }
-
+        v.setTranslationX(mStackPosition.x);
         final float yOffset =
                 getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_Y);
-
-        // Position the new bubble in the correct position, scaled down completely.
-        child.setTranslationX(mStackPosition.x);
-        child.setTranslationY(mStackPosition.y + yOffset * index);
-        child.setScaleX(0f);
-        child.setScaleY(0f);
-
-        // Push the subsequent views out of the way, if there are subsequent views.
-        if (index + 1 < mLayout.getChildCount()) {
-            animationForChildAtIndex(index + 1)
-                    .translationY(mStackPosition.y + yOffset * (index + 1))
-                    .withStiffness(SpringForce.STIFFNESS_LOW)
-                    .start();
-        }
-
-        // Scale in the new bubble, slightly delayed.
-        animationForChild(child)
+        final float endY = mStackPosition.y + yOffset * index;
+        final float startY = endY + NEW_BUBBLE_START_Y;
+        v.setTranslationY(startY);
+        v.setScaleX(NEW_BUBBLE_START_SCALE);
+        v.setScaleY(NEW_BUBBLE_START_SCALE);
+        v.setAlpha(0f);
+        final ViewPropertyAnimator animator = v.animate()
+                .translationY(endY)
                 .scaleX(1f)
                 .scaleY(1f)
-                .withStiffness(ANIMATE_IN_STIFFNESS)
-                .withStartDelay(mLayout.getChildCount() > 1 ? ANIMATE_IN_START_DELAY : 0)
-                .start();
+                .alpha(1f)
+                .setDuration(BUBBLE_SWAP_DURATION)
+                .withEndAction(() -> {
+                    v.setTag(R.id.reorder_animator_tag, null);
+                });
+        v.setTag(R.id.reorder_animator_tag, animator);
     }
 
     /**
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
index 6c6c5c9..8a10599 100644
--- a/libs/androidfw/LocaleDataTables.cpp
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -64,42 +64,43 @@
     /* 60 */ {'N', 'k', 'o', 'o'},
     /* 61 */ {'N', 's', 'h', 'u'},
     /* 62 */ {'O', 'g', 'a', 'm'},
-    /* 63 */ {'O', 'r', 'k', 'h'},
-    /* 64 */ {'O', 'r', 'y', 'a'},
-    /* 65 */ {'O', 's', 'g', 'e'},
-    /* 66 */ {'P', 'a', 'u', 'c'},
-    /* 67 */ {'P', 'h', 'l', 'i'},
-    /* 68 */ {'P', 'h', 'n', 'x'},
-    /* 69 */ {'P', 'l', 'r', 'd'},
-    /* 70 */ {'P', 'r', 't', 'i'},
-    /* 71 */ {'R', 'u', 'n', 'r'},
-    /* 72 */ {'S', 'a', 'm', 'r'},
-    /* 73 */ {'S', 'a', 'r', 'b'},
-    /* 74 */ {'S', 'a', 'u', 'r'},
-    /* 75 */ {'S', 'g', 'n', 'w'},
-    /* 76 */ {'S', 'i', 'n', 'h'},
-    /* 77 */ {'S', 'o', 'g', 'd'},
-    /* 78 */ {'S', 'o', 'r', 'a'},
-    /* 79 */ {'S', 'o', 'y', 'o'},
-    /* 80 */ {'S', 'y', 'r', 'c'},
-    /* 81 */ {'T', 'a', 'l', 'e'},
-    /* 82 */ {'T', 'a', 'l', 'u'},
-    /* 83 */ {'T', 'a', 'm', 'l'},
-    /* 84 */ {'T', 'a', 'n', 'g'},
-    /* 85 */ {'T', 'a', 'v', 't'},
-    /* 86 */ {'T', 'e', 'l', 'u'},
-    /* 87 */ {'T', 'f', 'n', 'g'},
-    /* 88 */ {'T', 'h', 'a', 'a'},
-    /* 89 */ {'T', 'h', 'a', 'i'},
-    /* 90 */ {'T', 'i', 'b', 't'},
-    /* 91 */ {'U', 'g', 'a', 'r'},
-    /* 92 */ {'V', 'a', 'i', 'i'},
-    /* 93 */ {'W', 'c', 'h', 'o'},
-    /* 94 */ {'X', 'p', 'e', 'o'},
-    /* 95 */ {'X', 's', 'u', 'x'},
-    /* 96 */ {'Y', 'i', 'i', 'i'},
-    /* 97 */ {'~', '~', '~', 'A'},
-    /* 98 */ {'~', '~', '~', 'B'},
+    /* 63 */ {'O', 'l', 'c', 'k'},
+    /* 64 */ {'O', 'r', 'k', 'h'},
+    /* 65 */ {'O', 'r', 'y', 'a'},
+    /* 66 */ {'O', 's', 'g', 'e'},
+    /* 67 */ {'P', 'a', 'u', 'c'},
+    /* 68 */ {'P', 'h', 'l', 'i'},
+    /* 69 */ {'P', 'h', 'n', 'x'},
+    /* 70 */ {'P', 'l', 'r', 'd'},
+    /* 71 */ {'P', 'r', 't', 'i'},
+    /* 72 */ {'R', 'u', 'n', 'r'},
+    /* 73 */ {'S', 'a', 'm', 'r'},
+    /* 74 */ {'S', 'a', 'r', 'b'},
+    /* 75 */ {'S', 'a', 'u', 'r'},
+    /* 76 */ {'S', 'g', 'n', 'w'},
+    /* 77 */ {'S', 'i', 'n', 'h'},
+    /* 78 */ {'S', 'o', 'g', 'd'},
+    /* 79 */ {'S', 'o', 'r', 'a'},
+    /* 80 */ {'S', 'o', 'y', 'o'},
+    /* 81 */ {'S', 'y', 'r', 'c'},
+    /* 82 */ {'T', 'a', 'l', 'e'},
+    /* 83 */ {'T', 'a', 'l', 'u'},
+    /* 84 */ {'T', 'a', 'm', 'l'},
+    /* 85 */ {'T', 'a', 'n', 'g'},
+    /* 86 */ {'T', 'a', 'v', 't'},
+    /* 87 */ {'T', 'e', 'l', 'u'},
+    /* 88 */ {'T', 'f', 'n', 'g'},
+    /* 89 */ {'T', 'h', 'a', 'a'},
+    /* 90 */ {'T', 'h', 'a', 'i'},
+    /* 91 */ {'T', 'i', 'b', 't'},
+    /* 92 */ {'U', 'g', 'a', 'r'},
+    /* 93 */ {'V', 'a', 'i', 'i'},
+    /* 94 */ {'W', 'c', 'h', 'o'},
+    /* 95 */ {'X', 'p', 'e', 'o'},
+    /* 96 */ {'X', 's', 'u', 'x'},
+    /* 97 */ {'Y', 'i', 'i', 'i'},
+    /* 98 */ {'~', '~', '~', 'A'},
+    /* 99 */ {'~', '~', '~', 'B'},
 };
 
 
@@ -120,7 +121,7 @@
     {0x80600000u, 46u}, // ada -> Latn
     {0x90600000u, 46u}, // ade -> Latn
     {0xA4600000u, 46u}, // adj -> Latn
-    {0xBC600000u, 90u}, // adp -> Tibt
+    {0xBC600000u, 91u}, // adp -> Tibt
     {0xE0600000u, 17u}, // ady -> Cyrl
     {0xE4600000u, 46u}, // adz -> Latn
     {0x61650000u,  4u}, // ae -> Avst
@@ -138,7 +139,7 @@
     {0xB8E00000u,  0u}, // aho -> Ahom
     {0x99200000u, 46u}, // ajg -> Latn
     {0x616B0000u, 46u}, // ak -> Latn
-    {0xA9400000u, 95u}, // akk -> Xsux
+    {0xA9400000u, 96u}, // akk -> Xsux
     {0x81600000u, 46u}, // ala -> Latn
     {0xA1600000u, 46u}, // ali -> Latn
     {0xB5600000u, 46u}, // aln -> Latn
@@ -163,7 +164,7 @@
     {0xC9E00000u, 46u}, // aps -> Latn
     {0xE5E00000u, 46u}, // apz -> Latn
     {0x61720000u,  1u}, // ar -> Arab
-    {0x61725842u, 98u}, // ar-XB -> ~~~B
+    {0x61725842u, 99u}, // ar-XB -> ~~~B
     {0x8A200000u,  2u}, // arc -> Armi
     {0x9E200000u, 46u}, // arh -> Latn
     {0xB6200000u, 46u}, // arn -> Latn
@@ -174,7 +175,7 @@
     {0xE6200000u,  1u}, // arz -> Arab
     {0x61730000u,  7u}, // as -> Beng
     {0x82400000u, 46u}, // asa -> Latn
-    {0x92400000u, 75u}, // ase -> Sgnw
+    {0x92400000u, 76u}, // ase -> Sgnw
     {0x9A400000u, 46u}, // asg -> Latn
     {0xBA400000u, 46u}, // aso -> Latn
     {0xCE400000u, 46u}, // ast -> Latn
@@ -231,7 +232,7 @@
     {0xDC810000u, 46u}, // bex -> Latn
     {0xE4810000u, 46u}, // bez -> Latn
     {0x8CA10000u, 46u}, // bfd -> Latn
-    {0xC0A10000u, 83u}, // bfq -> Taml
+    {0xC0A10000u, 84u}, // bfq -> Taml
     {0xCCA10000u,  1u}, // bft -> Arab
     {0xE0A10000u, 18u}, // bfy -> Deva
     {0x62670000u, 17u}, // bg -> Cyrl
@@ -265,7 +266,7 @@
     {0xC1410000u, 46u}, // bkq -> Latn
     {0xD1410000u, 46u}, // bku -> Latn
     {0xD5410000u, 46u}, // bkv -> Latn
-    {0xCD610000u, 85u}, // blt -> Tavt
+    {0xCD610000u, 86u}, // blt -> Tavt
     {0x626D0000u, 46u}, // bm -> Latn
     {0x9D810000u, 46u}, // bmh -> Latn
     {0xA9810000u, 46u}, // bmk -> Latn
@@ -275,7 +276,7 @@
     {0x99A10000u, 46u}, // bng -> Latn
     {0xB1A10000u, 46u}, // bnm -> Latn
     {0xBDA10000u, 46u}, // bnp -> Latn
-    {0x626F0000u, 90u}, // bo -> Tibt
+    {0x626F0000u, 91u}, // bo -> Tibt
     {0xA5C10000u, 46u}, // boj -> Latn
     {0xB1C10000u, 46u}, // bom -> Latn
     {0xB5C10000u, 46u}, // bon -> Latn
@@ -322,6 +323,7 @@
     {0x9F210000u, 46u}, // bzh -> Latn
     {0xDB210000u, 46u}, // bzw -> Latn
     {0x63610000u, 46u}, // ca -> Latn
+    {0x8C020000u, 46u}, // cad -> Latn
     {0xB4020000u, 46u}, // can -> Latn
     {0xA4220000u, 46u}, // cbj -> Latn
     {0x9C420000u, 46u}, // cch -> Latn
@@ -346,7 +348,7 @@
     {0xE1420000u, 46u}, // cky -> Latn
     {0x81620000u, 46u}, // cla -> Latn
     {0x91820000u, 46u}, // cme -> Latn
-    {0x99820000u, 79u}, // cmg -> Soyo
+    {0x99820000u, 80u}, // cmg -> Soyo
     {0x636F0000u, 46u}, // co -> Latn
     {0xBDC20000u, 15u}, // cop -> Copt
     {0xC9E20000u, 46u}, // cps -> Latn
@@ -360,7 +362,7 @@
     {0x63730000u, 46u}, // cs -> Latn
     {0x86420000u, 46u}, // csb -> Latn
     {0xDA420000u, 10u}, // csw -> Cans
-    {0x8E620000u, 66u}, // ctd -> Pauc
+    {0x8E620000u, 67u}, // ctd -> Pauc
     {0x63750000u, 17u}, // cu -> Cyrl
     {0x63760000u, 17u}, // cv -> Cyrl
     {0x63790000u, 46u}, // cy -> Latn
@@ -389,7 +391,7 @@
     {0x91230000u, 46u}, // dje -> Latn
     {0xA5A30000u, 46u}, // dnj -> Latn
     {0x85C30000u, 46u}, // dob -> Latn
-    {0xA1C30000u,  1u}, // doi -> Arab
+    {0xA1C30000u, 18u}, // doi -> Deva
     {0xBDC30000u, 46u}, // dop -> Latn
     {0xD9C30000u, 46u}, // dow -> Latn
     {0x9E230000u, 56u}, // drh -> Mong
@@ -404,12 +406,12 @@
     {0x8A830000u, 46u}, // duc -> Latn
     {0x8E830000u, 46u}, // dud -> Latn
     {0x9A830000u, 46u}, // dug -> Latn
-    {0x64760000u, 88u}, // dv -> Thaa
+    {0x64760000u, 89u}, // dv -> Thaa
     {0x82A30000u, 46u}, // dva -> Latn
     {0xDAC30000u, 46u}, // dww -> Latn
     {0xBB030000u, 46u}, // dyo -> Latn
     {0xD3030000u, 46u}, // dyu -> Latn
-    {0x647A0000u, 90u}, // dz -> Tibt
+    {0x647A0000u, 91u}, // dz -> Tibt
     {0x9B230000u, 46u}, // dzg -> Latn
     {0xD0240000u, 46u}, // ebu -> Latn
     {0x65650000u, 46u}, // ee -> Latn
@@ -422,7 +424,7 @@
     {0x81840000u, 46u}, // ema -> Latn
     {0xA1840000u, 46u}, // emi -> Latn
     {0x656E0000u, 46u}, // en -> Latn
-    {0x656E5841u, 97u}, // en-XA -> ~~~A
+    {0x656E5841u, 98u}, // en-XA -> ~~~A
     {0xB5A40000u, 46u}, // enn -> Latn
     {0xC1A40000u, 46u}, // enq -> Latn
     {0x656F0000u, 46u}, // eo -> Latn
@@ -438,6 +440,7 @@
     {0x65750000u, 46u}, // eu -> Latn
     {0xBAC40000u, 46u}, // ewo -> Latn
     {0xCEE40000u, 46u}, // ext -> Latn
+    {0x83240000u, 46u}, // eza -> Latn
     {0x66610000u,  1u}, // fa -> Arab
     {0x80050000u, 46u}, // faa -> Latn
     {0x84050000u, 46u}, // fab -> Latn
@@ -521,7 +524,7 @@
     {0x95C60000u, 20u}, // gof -> Ethi
     {0xA1C60000u, 46u}, // goi -> Latn
     {0xB1C60000u, 18u}, // gom -> Deva
-    {0xB5C60000u, 86u}, // gon -> Telu
+    {0xB5C60000u, 87u}, // gon -> Telu
     {0xC5C60000u, 46u}, // gor -> Latn
     {0xC9C60000u, 46u}, // gos -> Latn
     {0xCDC60000u, 24u}, // got -> Goth
@@ -566,7 +569,7 @@
     {0xAD070000u, 46u}, // hil -> Latn
     {0x81670000u, 46u}, // hla -> Latn
     {0xD1670000u, 32u}, // hlu -> Hluw
-    {0x8D870000u, 69u}, // hmd -> Plrd
+    {0x8D870000u, 70u}, // hmd -> Plrd
     {0xCD870000u, 46u}, // hmt -> Latn
     {0x8DA70000u,  1u}, // hnd -> Arab
     {0x91A70000u, 18u}, // hne -> Deva
@@ -601,7 +604,7 @@
     {0x69670000u, 46u}, // ig -> Latn
     {0x84C80000u, 46u}, // igb -> Latn
     {0x90C80000u, 46u}, // ige -> Latn
-    {0x69690000u, 96u}, // ii -> Yiii
+    {0x69690000u, 97u}, // ii -> Yiii
     {0xA5280000u, 46u}, // ijj -> Latn
     {0x696B0000u, 46u}, // ik -> Latn
     {0xA9480000u, 46u}, // ikk -> Latn
@@ -626,6 +629,7 @@
     {0x6A610000u, 36u}, // ja -> Jpan
     {0x84090000u, 46u}, // jab -> Latn
     {0xB0090000u, 46u}, // jam -> Latn
+    {0xC4090000u, 46u}, // jar -> Latn
     {0xB8290000u, 46u}, // jbo -> Latn
     {0xD0290000u, 46u}, // jbu -> Latn
     {0xB4890000u, 46u}, // jen -> Latn
@@ -661,7 +665,7 @@
     {0x906A0000u, 46u}, // kde -> Latn
     {0x9C6A0000u,  1u}, // kdh -> Arab
     {0xAC6A0000u, 46u}, // kdl -> Latn
-    {0xCC6A0000u, 89u}, // kdt -> Thai
+    {0xCC6A0000u, 90u}, // kdt -> Thai
     {0x808A0000u, 46u}, // kea -> Latn
     {0xB48A0000u, 46u}, // ken -> Latn
     {0xE48A0000u, 46u}, // kez -> Latn
@@ -673,7 +677,7 @@
     {0x94CA0000u, 46u}, // kgf -> Latn
     {0xBCCA0000u, 46u}, // kgp -> Latn
     {0x80EA0000u, 46u}, // kha -> Latn
-    {0x84EA0000u, 82u}, // khb -> Talu
+    {0x84EA0000u, 83u}, // khb -> Talu
     {0xB4EA0000u, 18u}, // khn -> Deva
     {0xC0EA0000u, 46u}, // khq -> Latn
     {0xC8EA0000u, 46u}, // khs -> Latn
@@ -766,7 +770,8 @@
     {0x82EA0000u, 46u}, // kxa -> Latn
     {0x8AEA0000u, 20u}, // kxc -> Ethi
     {0x92EA0000u, 46u}, // kxe -> Latn
-    {0xB2EA0000u, 89u}, // kxm -> Thai
+    {0xAEEA0000u, 18u}, // kxl -> Deva
+    {0xB2EA0000u, 90u}, // kxm -> Thai
     {0xBEEA0000u,  1u}, // kxp -> Arab
     {0xDAEA0000u, 46u}, // kxw -> Latn
     {0xE6EA0000u, 46u}, // kxz -> Latn
@@ -775,6 +780,7 @@
     {0x6B795452u, 46u}, // ky-TR -> Latn
     {0x930A0000u, 46u}, // kye -> Latn
     {0xDF0A0000u, 46u}, // kyx -> Latn
+    {0x9F2A0000u,  1u}, // kzh -> Arab
     {0xA72A0000u, 46u}, // kzj -> Latn
     {0xC72A0000u, 46u}, // kzr -> Latn
     {0xCF2A0000u, 46u}, // kzt -> Latn
@@ -790,7 +796,7 @@
     {0xD02B0000u, 46u}, // lbu -> Latn
     {0xD82B0000u, 46u}, // lbw -> Latn
     {0xB04B0000u, 46u}, // lcm -> Latn
-    {0xBC4B0000u, 89u}, // lcp -> Thai
+    {0xBC4B0000u, 90u}, // lcp -> Thai
     {0x846B0000u, 46u}, // ldb -> Latn
     {0x8C8B0000u, 46u}, // led -> Latn
     {0x908B0000u, 46u}, // lee -> Latn
@@ -814,7 +820,7 @@
     {0xCD4B0000u, 46u}, // lkt -> Latn
     {0x916B0000u, 46u}, // lle -> Latn
     {0xB56B0000u, 46u}, // lln -> Latn
-    {0xB58B0000u, 86u}, // lmn -> Telu
+    {0xB58B0000u, 87u}, // lmn -> Telu
     {0xB98B0000u, 46u}, // lmo -> Latn
     {0xBD8B0000u, 46u}, // lmp -> Latn
     {0x6C6E0000u, 46u}, // ln -> Latn
@@ -836,7 +842,7 @@
     {0xE28B0000u, 46u}, // luy -> Latn
     {0xE68B0000u,  1u}, // luz -> Arab
     {0x6C760000u, 46u}, // lv -> Latn
-    {0xAECB0000u, 89u}, // lwl -> Thai
+    {0xAECB0000u, 90u}, // lwl -> Thai
     {0x9F2B0000u, 28u}, // lzh -> Hans
     {0xE72B0000u, 46u}, // lzz -> Latn
     {0x8C0C0000u, 46u}, // mad -> Latn
@@ -927,7 +933,6 @@
     {0xBA2C0000u, 57u}, // mro -> Mroo
     {0x6D730000u, 46u}, // ms -> Latn
     {0x6D734343u,  1u}, // ms-CC -> Arab
-    {0x6D734944u,  1u}, // ms-ID -> Arab
     {0x6D740000u, 46u}, // mt -> Latn
     {0x8A6C0000u, 46u}, // mtc -> Latn
     {0x966C0000u, 46u}, // mtf -> Latn
@@ -1006,11 +1011,11 @@
     {0x9DAD0000u, 46u}, // nnh -> Latn
     {0xA9AD0000u, 46u}, // nnk -> Latn
     {0xB1AD0000u, 46u}, // nnm -> Latn
-    {0xBDAD0000u, 93u}, // nnp -> Wcho
+    {0xBDAD0000u, 94u}, // nnp -> Wcho
     {0x6E6F0000u, 46u}, // no -> Latn
     {0x8DCD0000u, 44u}, // nod -> Lana
     {0x91CD0000u, 18u}, // noe -> Deva
-    {0xB5CD0000u, 71u}, // non -> Runr
+    {0xB5CD0000u, 72u}, // non -> Runr
     {0xBDCD0000u, 46u}, // nop -> Latn
     {0xD1CD0000u, 46u}, // nou -> Latn
     {0xBA0D0000u, 60u}, // nqo -> Nkoo
@@ -1044,18 +1049,18 @@
     {0xB5AE0000u, 46u}, // onn -> Latn
     {0xC9AE0000u, 46u}, // ons -> Latn
     {0xB1EE0000u, 46u}, // opm -> Latn
-    {0x6F720000u, 64u}, // or -> Orya
+    {0x6F720000u, 65u}, // or -> Orya
     {0xBA2E0000u, 46u}, // oro -> Latn
     {0xD22E0000u,  1u}, // oru -> Arab
     {0x6F730000u, 17u}, // os -> Cyrl
-    {0x824E0000u, 65u}, // osa -> Osge
+    {0x824E0000u, 66u}, // osa -> Osge
     {0x826E0000u,  1u}, // ota -> Arab
-    {0xAA6E0000u, 63u}, // otk -> Orkh
+    {0xAA6E0000u, 64u}, // otk -> Orkh
     {0xB32E0000u, 46u}, // ozm -> Latn
     {0x70610000u, 27u}, // pa -> Guru
     {0x7061504Bu,  1u}, // pa-PK -> Arab
     {0x980F0000u, 46u}, // pag -> Latn
-    {0xAC0F0000u, 67u}, // pal -> Phli
+    {0xAC0F0000u, 68u}, // pal -> Phli
     {0xB00F0000u, 46u}, // pam -> Latn
     {0xBC0F0000u, 46u}, // pap -> Latn
     {0xD00F0000u, 46u}, // pau -> Latn
@@ -1065,11 +1070,11 @@
     {0x886F0000u, 46u}, // pdc -> Latn
     {0xCC6F0000u, 46u}, // pdt -> Latn
     {0x8C8F0000u, 46u}, // ped -> Latn
-    {0xB88F0000u, 94u}, // peo -> Xpeo
+    {0xB88F0000u, 95u}, // peo -> Xpeo
     {0xDC8F0000u, 46u}, // pex -> Latn
     {0xACAF0000u, 46u}, // pfl -> Latn
     {0xACEF0000u,  1u}, // phl -> Arab
-    {0xB4EF0000u, 68u}, // phn -> Phnx
+    {0xB4EF0000u, 69u}, // phn -> Phnx
     {0xAD0F0000u, 46u}, // pil -> Latn
     {0xBD0F0000u, 46u}, // pip -> Latn
     {0x814F0000u,  8u}, // pka -> Brah
@@ -1105,7 +1110,7 @@
     {0xB4D10000u, 46u}, // rgn -> Latn
     {0x98F10000u,  1u}, // rhg -> Arab
     {0x81110000u, 46u}, // ria -> Latn
-    {0x95110000u, 87u}, // rif -> Tfng
+    {0x95110000u, 88u}, // rif -> Tfng
     {0x95114E4Cu, 46u}, // rif-NL -> Latn
     {0xC9310000u, 18u}, // rjs -> Deva
     {0xCD510000u,  7u}, // rkt -> Beng
@@ -1135,9 +1140,9 @@
     {0x9C120000u, 17u}, // sah -> Cyrl
     {0xC0120000u, 46u}, // saq -> Latn
     {0xC8120000u, 46u}, // sas -> Latn
-    {0xCC120000u, 46u}, // sat -> Latn
+    {0xCC120000u, 63u}, // sat -> Olck
     {0xD4120000u, 46u}, // sav -> Latn
-    {0xE4120000u, 74u}, // saz -> Saur
+    {0xE4120000u, 75u}, // saz -> Saur
     {0x80320000u, 46u}, // sba -> Latn
     {0x90320000u, 46u}, // sbe -> Latn
     {0xBC320000u, 46u}, // sbp -> Latn
@@ -1161,11 +1166,11 @@
     {0xD8D20000u, 20u}, // sgw -> Ethi
     {0xE4D20000u, 46u}, // sgz -> Latn
     {0x73680000u, 46u}, // sh -> Latn
-    {0xA0F20000u, 87u}, // shi -> Tfng
+    {0xA0F20000u, 88u}, // shi -> Tfng
     {0xA8F20000u, 46u}, // shk -> Latn
     {0xB4F20000u, 58u}, // shn -> Mymr
     {0xD0F20000u,  1u}, // shu -> Arab
-    {0x73690000u, 76u}, // si -> Sinh
+    {0x73690000u, 77u}, // si -> Sinh
     {0x8D120000u, 46u}, // sid -> Latn
     {0x99120000u, 46u}, // sig -> Latn
     {0xAD120000u, 46u}, // sil -> Latn
@@ -1184,7 +1189,7 @@
     {0x81920000u, 46u}, // sma -> Latn
     {0xA5920000u, 46u}, // smj -> Latn
     {0xB5920000u, 46u}, // smn -> Latn
-    {0xBD920000u, 72u}, // smp -> Samr
+    {0xBD920000u, 73u}, // smp -> Samr
     {0xC1920000u, 46u}, // smq -> Latn
     {0xC9920000u, 46u}, // sms -> Latn
     {0x736E0000u, 46u}, // sn -> Latn
@@ -1194,10 +1199,10 @@
     {0xDDB20000u, 46u}, // snx -> Latn
     {0xE1B20000u, 46u}, // sny -> Latn
     {0x736F0000u, 46u}, // so -> Latn
-    {0x99D20000u, 77u}, // sog -> Sogd
+    {0x99D20000u, 78u}, // sog -> Sogd
     {0xA9D20000u, 46u}, // sok -> Latn
     {0xC1D20000u, 46u}, // soq -> Latn
-    {0xD1D20000u, 89u}, // sou -> Thai
+    {0xD1D20000u, 90u}, // sou -> Thai
     {0xE1D20000u, 46u}, // soy -> Latn
     {0x8DF20000u, 46u}, // spd -> Latn
     {0xADF20000u, 46u}, // spl -> Latn
@@ -1208,7 +1213,7 @@
     {0x7372524Fu, 46u}, // sr-RO -> Latn
     {0x73725255u, 46u}, // sr-RU -> Latn
     {0x73725452u, 46u}, // sr-TR -> Latn
-    {0x86320000u, 78u}, // srb -> Sora
+    {0x86320000u, 79u}, // srb -> Sora
     {0xB6320000u, 46u}, // srn -> Latn
     {0xC6320000u, 46u}, // srr -> Latn
     {0xDE320000u, 18u}, // srx -> Deva
@@ -1235,9 +1240,9 @@
     {0xB6F20000u, 46u}, // sxn -> Latn
     {0xDAF20000u, 46u}, // sxw -> Latn
     {0xAF120000u,  7u}, // syl -> Beng
-    {0xC7120000u, 80u}, // syr -> Syrc
+    {0xC7120000u, 81u}, // syr -> Syrc
     {0xAF320000u, 46u}, // szl -> Latn
-    {0x74610000u, 83u}, // ta -> Taml
+    {0x74610000u, 84u}, // ta -> Taml
     {0xA4130000u, 18u}, // taj -> Deva
     {0xAC130000u, 46u}, // tal -> Latn
     {0xB4130000u, 46u}, // tan -> Latn
@@ -1251,11 +1256,11 @@
     {0xE4330000u, 46u}, // tbz -> Latn
     {0xA0530000u, 46u}, // tci -> Latn
     {0xE0530000u, 42u}, // tcy -> Knda
-    {0x8C730000u, 81u}, // tdd -> Tale
+    {0x8C730000u, 82u}, // tdd -> Tale
     {0x98730000u, 18u}, // tdg -> Deva
     {0x9C730000u, 18u}, // tdh -> Deva
     {0xD0730000u, 46u}, // tdu -> Latn
-    {0x74650000u, 86u}, // te -> Telu
+    {0x74650000u, 87u}, // te -> Telu
     {0x8C930000u, 46u}, // ted -> Latn
     {0xB0930000u, 46u}, // tem -> Latn
     {0xB8930000u, 46u}, // teo -> Latn
@@ -1266,7 +1271,7 @@
     {0x88D30000u, 46u}, // tgc -> Latn
     {0xB8D30000u, 46u}, // tgo -> Latn
     {0xD0D30000u, 46u}, // tgu -> Latn
-    {0x74680000u, 89u}, // th -> Thai
+    {0x74680000u, 90u}, // th -> Thai
     {0xACF30000u, 18u}, // thl -> Deva
     {0xC0F30000u, 18u}, // thq -> Deva
     {0xC4F30000u, 18u}, // thr -> Deva
@@ -1305,14 +1310,14 @@
     {0x8E530000u, 25u}, // tsd -> Grek
     {0x96530000u, 18u}, // tsf -> Deva
     {0x9A530000u, 46u}, // tsg -> Latn
-    {0xA6530000u, 90u}, // tsj -> Tibt
+    {0xA6530000u, 91u}, // tsj -> Tibt
     {0xDA530000u, 46u}, // tsw -> Latn
     {0x74740000u, 17u}, // tt -> Cyrl
     {0x8E730000u, 46u}, // ttd -> Latn
     {0x92730000u, 46u}, // tte -> Latn
     {0xA6730000u, 46u}, // ttj -> Latn
     {0xC6730000u, 46u}, // ttr -> Latn
-    {0xCA730000u, 89u}, // tts -> Thai
+    {0xCA730000u, 90u}, // tts -> Thai
     {0xCE730000u, 46u}, // ttt -> Latn
     {0x9E930000u, 46u}, // tuh -> Latn
     {0xAE930000u, 46u}, // tul -> Latn
@@ -1323,7 +1328,7 @@
     {0xD2B30000u, 46u}, // tvu -> Latn
     {0x9ED30000u, 46u}, // twh -> Latn
     {0xC2D30000u, 46u}, // twq -> Latn
-    {0x9AF30000u, 84u}, // txg -> Tang
+    {0x9AF30000u, 85u}, // txg -> Tang
     {0x74790000u, 46u}, // ty -> Latn
     {0x83130000u, 46u}, // tya -> Latn
     {0xD7130000u, 17u}, // tyv -> Cyrl
@@ -1333,7 +1338,7 @@
     {0x75670000u,  1u}, // ug -> Arab
     {0x75674B5Au, 17u}, // ug-KZ -> Cyrl
     {0x75674D4Eu, 17u}, // ug-MN -> Cyrl
-    {0x80D40000u, 91u}, // uga -> Ugar
+    {0x80D40000u, 92u}, // uga -> Ugar
     {0x756B0000u, 17u}, // uk -> Cyrl
     {0xA1740000u, 46u}, // uli -> Latn
     {0x85940000u, 46u}, // umb -> Latn
@@ -1346,6 +1351,7 @@
     {0xCE340000u, 46u}, // urt -> Latn
     {0xDA340000u, 46u}, // urw -> Latn
     {0x82540000u, 46u}, // usa -> Latn
+    {0x9E740000u, 46u}, // uth -> Latn
     {0xC6740000u, 46u}, // utr -> Latn
     {0x9EB40000u, 46u}, // uvh -> Latn
     {0xAEB40000u, 46u}, // uvl -> Latn
@@ -1353,7 +1359,7 @@
     {0x757A4146u,  1u}, // uz-AF -> Arab
     {0x757A434Eu, 17u}, // uz-CN -> Cyrl
     {0x98150000u, 46u}, // vag -> Latn
-    {0xA0150000u, 92u}, // vai -> Vaii
+    {0xA0150000u, 93u}, // vai -> Vaii
     {0xB4150000u, 46u}, // van -> Latn
     {0x76650000u, 46u}, // ve -> Latn
     {0x88950000u, 46u}, // vec -> Latn
@@ -1376,7 +1382,7 @@
     {0xB4160000u, 46u}, // wan -> Latn
     {0xC4160000u, 46u}, // war -> Latn
     {0xBC360000u, 46u}, // wbp -> Latn
-    {0xC0360000u, 86u}, // wbq -> Telu
+    {0xC0360000u, 87u}, // wbq -> Telu
     {0xC4360000u, 18u}, // wbr -> Deva
     {0xA0560000u, 46u}, // wci -> Latn
     {0xC4960000u, 46u}, // wer -> Latn
@@ -1418,9 +1424,9 @@
     {0xC5B70000u, 18u}, // xnr -> Deva
     {0x99D70000u, 46u}, // xog -> Latn
     {0xB5D70000u, 46u}, // xon -> Latn
-    {0xC5F70000u, 70u}, // xpr -> Prti
+    {0xC5F70000u, 71u}, // xpr -> Prti
     {0x86370000u, 46u}, // xrb -> Latn
-    {0x82570000u, 73u}, // xsa -> Sarb
+    {0x82570000u, 74u}, // xsa -> Sarb
     {0xA2570000u, 46u}, // xsi -> Latn
     {0xB2570000u, 46u}, // xsm -> Latn
     {0xC6570000u, 18u}, // xsr -> Deva
@@ -1461,7 +1467,7 @@
     {0x98190000u, 46u}, // zag -> Latn
     {0xA4790000u,  1u}, // zdj -> Arab
     {0x80990000u, 46u}, // zea -> Latn
-    {0x9CD90000u, 87u}, // zgh -> Tfng
+    {0x9CD90000u, 88u}, // zgh -> Tfng
     {0x7A680000u, 28u}, // zh -> Hans
     {0x7A684155u, 29u}, // zh-AU -> Hant
     {0x7A68424Eu, 29u}, // zh-BN -> Hant
@@ -1470,7 +1476,6 @@
     {0x7A68484Bu, 29u}, // zh-HK -> Hant
     {0x7A684944u, 29u}, // zh-ID -> Hant
     {0x7A684D4Fu, 29u}, // zh-MO -> Hant
-    {0x7A684D59u, 29u}, // zh-MY -> Hant
     {0x7A685041u, 29u}, // zh-PA -> Hant
     {0x7A685046u, 29u}, // zh-PF -> Hant
     {0x7A685048u, 29u}, // zh-PH -> Hant
@@ -1592,6 +1597,7 @@
     0xD701434D4C61746ELLU, // byv_Latn_CM
     0x93214D4C4C61746ELLU, // bze_Latn_ML
     0x636145534C61746ELLU, // ca_Latn_ES
+    0x8C0255534C61746ELLU, // cad_Latn_US
     0x9C424E474C61746ELLU, // cch_Latn_NG
     0xBC42424443616B6DLLU, // ccp_Cakm_BD
     0x636552554379726CLLU, // ce_Cyrl_RU
@@ -1627,6 +1633,7 @@
     0x637652554379726CLLU, // cv_Cyrl_RU
     0x637947424C61746ELLU, // cy_Latn_GB
     0x6461444B4C61746ELLU, // da_Latn_DK
+    0x940343494C61746ELLU, // daf_Latn_CI
     0xA80355534C61746ELLU, // dak_Latn_US
     0xC40352554379726CLLU, // dar_Cyrl_RU
     0xD4034B454C61746ELLU, // dav_Latn_KE
@@ -1636,7 +1643,7 @@
     0xC4C343414C61746ELLU, // dgr_Latn_CA
     0x91234E454C61746ELLU, // dje_Latn_NE
     0xA5A343494C61746ELLU, // dnj_Latn_CI
-    0xA1C3494E41726162LLU, // doi_Arab_IN
+    0xA1C3494E44657661LLU, // doi_Deva_IN
     0x9E23434E4D6F6E67LLU, // drh_Mong_CN
     0x864344454C61746ELLU, // dsb_Latn_DE
     0xB2634D4C4C61746ELLU, // dtm_Latn_ML
@@ -1839,6 +1846,7 @@
     0xC6AA49444C61746ELLU, // kvr_Latn_ID
     0xDEAA504B41726162LLU, // kvx_Arab_PK
     0x6B7747424C61746ELLU, // kw_Latn_GB
+    0xAEEA494E44657661LLU, // kxl_Deva_IN
     0xB2EA544854686169LLU, // kxm_Thai_TH
     0xBEEA504B41726162LLU, // kxp_Arab_PK
     0x6B79434E41726162LLU, // ky_Arab_CN
@@ -2047,7 +2055,7 @@
     0x9C1252554379726CLLU, // sah_Cyrl_RU
     0xC0124B454C61746ELLU, // saq_Latn_KE
     0xC81249444C61746ELLU, // sas_Latn_ID
-    0xCC12494E4C61746ELLU, // sat_Latn_IN
+    0xCC12494E4F6C636BLLU, // sat_Olck_IN
     0xD412534E4C61746ELLU, // sav_Latn_SN
     0xE412494E53617572LLU, // saz_Saur_IN
     0xBC32545A4C61746ELLU, // sbp_Latn_TZ
@@ -2149,6 +2157,7 @@
     0x747254524C61746ELLU, // tr_Latn_TR
     0xD23354524C61746ELLU, // tru_Latn_TR
     0xD63354574C61746ELLU, // trv_Latn_TW
+    0xDA33504B41726162LLU, // trw_Arab_PK
     0x74735A414C61746ELLU, // ts_Latn_ZA
     0x8E5347524772656BLLU, // tsd_Grek_GR
     0x96534E5044657661LLU, // tsf_Deva_NP
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index bce70e2..2233827 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -30,6 +30,7 @@
 #include <memory>
 #include <set>
 #include <type_traits>
+#include <vector>
 
 #include <android-base/macros.h>
 #include <androidfw/ByteBucketArray.h>
@@ -1029,7 +1030,7 @@
             // But we don't want to hit the cache, so instead we will have a
             // local temporary allocation for the conversions.
             size_t convBufferLen = strLen + 4;
-            char16_t* convBuffer = (char16_t*)calloc(convBufferLen, sizeof(char16_t));
+            std::vector<char16_t> convBuffer(convBufferLen);
             ssize_t l = 0;
             ssize_t h = mHeader->stringCount-1;
 
@@ -1043,8 +1044,8 @@
                 }
                 if (s.has_value()) {
                     char16_t* end = utf8_to_utf16(reinterpret_cast<const uint8_t*>(s->data()),
-                                                  s->size(), convBuffer, convBufferLen);
-                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);
+                                                  s->size(), convBuffer.data(), convBufferLen);
+                    c = strzcmp16(convBuffer.data(), end-convBuffer.data(), str, strLen);
                 }
                 if (kDebugStringPoolNoisy) {
                     ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
@@ -1054,7 +1055,6 @@
                     if (kDebugStringPoolNoisy) {
                         ALOGI("MATCH!");
                     }
-                    free(convBuffer);
                     return mid;
                 } else if (c < 0) {
                     l = mid + 1;
@@ -1062,7 +1062,6 @@
                     h = mid - 1;
                 }
             }
-            free(convBuffer);
         } else {
             // It is unusual to get the ID from an unsorted string block...
             // most often this happens because we want to get IDs for style
diff --git a/media/jni/tuner/ClientHelper.h b/media/jni/tuner/ClientHelper.h
new file mode 100644
index 0000000..185b2f6
--- /dev/null
+++ b/media/jni/tuner/ClientHelper.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
+#define _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
+
+#include <android/binder_parcel_utils.h>
+#include <android/hardware/tv/tuner/1.1/types.h>
+
+using Status = ::ndk::ScopedAStatus;
+
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using namespace std;
+
+namespace android {
+
+struct ClientHelper {
+
+public:
+	static Result getServiceSpecificErrorCode(Status& s) {
+        if (s.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            return static_cast<Result>(s.getServiceSpecificError());
+        } else if (s.isOk()) {
+            return Result::SUCCESS;
+        }
+        return Result::UNKNOWN_ERROR;
+    }
+};
+}  // namespace android
+
+#endif  // _ANDROID_MEDIA_TV_CLIENT_HELPER_H_
\ No newline at end of file
diff --git a/media/jni/tuner/DemuxClient.cpp b/media/jni/tuner/DemuxClient.cpp
index 08b7398..7265dcc 100644
--- a/media/jni/tuner/DemuxClient.cpp
+++ b/media/jni/tuner/DemuxClient.cpp
@@ -23,20 +23,20 @@
 
 using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
 
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using ::android::hardware::tv::tuner::V1_0::Result;
 
 namespace android {
 
 /////////////// DemuxClient ///////////////////////
 
-// TODO: pending aidl interface
-DemuxClient::DemuxClient() {
-    //mTunerDemux = tunerDemux;
+DemuxClient::DemuxClient(shared_ptr<ITunerDemux> tunerDemux) {
+    mTunerDemux = tunerDemux;
     mId = -1;
 }
 
 DemuxClient::~DemuxClient() {
-    //mTunerDemux = NULL;
+    mTunerDemux = NULL;
     mDemux = NULL;
     mId = -1;
 }
@@ -47,12 +47,10 @@
 }
 
 Result DemuxClient::setFrontendDataSource(sp<FrontendClient> frontendClient) {
-    // TODO: pending aidl interface
-    /*if (mTunerDemux != NULL) {
-        // TODO: handle error message
-        mTunerDemux->setFrontendDataSource(frontendClient->getAidlFrontend());
-        return (int) Result::SUCCESS;
-    }*/
+    if (mTunerDemux != NULL) {
+        Status s = mTunerDemux->setFrontendDataSource(frontendClient->getAidlFrontend());
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mDemux != NULL) {
         Result res = mDemux->setFrontendDataSource(frontendClient->getId());
@@ -64,13 +62,23 @@
 
 sp<FilterClient> DemuxClient::openFilter(DemuxFilterType type, int bufferSize,
         sp<FilterClientCallback> cb) {
-    // TODO: pending aidl interface
+    if (mTunerDemux != NULL) {
+        shared_ptr<ITunerFilter> tunerFilter;
+        shared_ptr<TunerFilterCallback> callback =
+                ::ndk::SharedRefBase::make<TunerFilterCallback>(cb);
+        Status s = mTunerDemux->openFilter((int)type.mainType, getSubType(type),
+                    bufferSize, callback, &tunerFilter);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
+        return new FilterClient(type, tunerFilter);
+    }
 
     if (mDemux != NULL) {
         sp<HidlFilterCallback> callback = new HidlFilterCallback(cb);
         sp<IFilter> hidlFilter = openHidlFilter(type, bufferSize, callback);
         if (hidlFilter != NULL) {
-            sp<FilterClient> filterClient = new FilterClient(type);
+            sp<FilterClient> filterClient = new FilterClient(type, NULL);
             filterClient->setHidlFilter(hidlFilter);
             return filterClient;
         }
@@ -244,4 +252,21 @@
 
     return hidlDvr;
 }
+
+int DemuxClient::getSubType(DemuxFilterType filterType) {
+    switch (filterType.mainType) {
+        case DemuxFilterMainType::TS:
+            return (int)filterType.subType.tsFilterType();
+        case DemuxFilterMainType::MMTP:
+            return (int)filterType.subType.mmtpFilterType();
+        case DemuxFilterMainType::IP:
+            return (int)filterType.subType.ipFilterType();
+        case DemuxFilterMainType::TLV:
+            return (int)filterType.subType.tlvFilterType();
+        case DemuxFilterMainType::ALP:
+            return (int)filterType.subType.alpFilterType();
+        default:
+            return -1;
+    }
+}
 }  // namespace android
diff --git a/media/jni/tuner/DemuxClient.h b/media/jni/tuner/DemuxClient.h
index 2950dd4..ead61301 100644
--- a/media/jni/tuner/DemuxClient.h
+++ b/media/jni/tuner/DemuxClient.h
@@ -17,10 +17,11 @@
 #ifndef _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
 #define _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
 
-//#include <aidl/android/media/tv/tuner/ITunerDemux.h>
+#include <aidl/android/media/tv/tuner/ITunerDemux.h>
 #include <android/hardware/tv/tuner/1.0/IDemux.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "DvrClient.h"
 #include "DvrClientCallback.h"
 #include "FilterClient.h"
@@ -28,7 +29,8 @@
 #include "FrontendClient.h"
 #include "TimeFilterClient.h"
 
-//using ::aidl::android::media::tv::tuner::ITunerDemux;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::ITunerDemux;
 
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterType;
 using ::android::hardware::tv::tuner::V1_0::DvrType;
@@ -42,7 +44,7 @@
 struct DemuxClient : public RefBase {
 
 public:
-    DemuxClient();
+    DemuxClient(shared_ptr<ITunerDemux> tunerDemux);
     ~DemuxClient();
 
     // TODO: remove after migration to Tuner Service is done.
@@ -100,13 +102,13 @@
     sp<IFilter> openHidlFilter(DemuxFilterType type, int bufferSize, sp<HidlFilterCallback> cb);
     sp<ITimeFilter> openHidlTimeFilter();
     sp<IDvr> openHidlDvr(DvrType type, int bufferSize, sp<HidlDvrCallback> cb);
+    int getSubType(DemuxFilterType filterType);
 
     /**
      * An AIDL Tuner Demux Singleton assigned at the first time the Tuner Client
      * opens a demux. Default null when demux is not opened.
      */
-    // TODO: pending on aidl interface
-    //shared_ptr<ITunerDemux> mTunerDemux;
+    shared_ptr<ITunerDemux> mTunerDemux;
 
     /**
      * A Demux HAL interface that is ready before migrating to the TunerDemux.
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index 0aab5fe..f26560b 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -30,16 +30,14 @@
 
 /////////////// FilterClient ///////////////////////
 
-// TODO: pending aidl interface
-// TODO: add filter callback
-FilterClient::FilterClient(DemuxFilterType type) {
-    //mTunerFilter = tunerFilter;
+FilterClient::FilterClient(DemuxFilterType type, shared_ptr<ITunerFilter> tunerFilter) {
+    mTunerFilter = tunerFilter;
     mAvSharedHandle = NULL;
     checkIsMediaFilter(type);
 }
 
 FilterClient::~FilterClient() {
-    //mTunerFilter = NULL;
+    mTunerFilter = NULL;
     mFilter = NULL;
     mFilter_1_1 = NULL;
     mAvSharedHandle = NULL;
@@ -154,7 +152,12 @@
 }
 
 Result FilterClient::getId(uint32_t& id) {
-    // TODO: pending aidl interface
+    if (mTunerFilter != NULL) {
+        int32_t id32Bit;
+        Status s = mTunerFilter->getId(&id32Bit);
+        id = static_cast<uint32_t>(id32Bit);
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mFilter != NULL) {
         Result res;
@@ -169,7 +172,12 @@
 }
 
 Result FilterClient::getId64Bit(uint64_t& id) {
-    // TODO: pending aidl interface
+    if (mTunerFilter != NULL) {
+        int64_t id64Bit;
+        Status s = mTunerFilter->getId64Bit(&id64Bit);
+        id = static_cast<uint64_t>(id64Bit);
+        return ClientHelper::getServiceSpecificErrorCode(s);
+    }
 
     if (mFilter_1_1 != NULL) {
         Result res;
@@ -248,6 +256,19 @@
     return Void();
 }
 
+/////////////// TunerFilterCallback ///////////////////////
+
+TunerFilterCallback::TunerFilterCallback(sp<FilterClientCallback> filterClientCallback)
+        : mFilterClientCallback(filterClientCallback) {}
+
+Status TunerFilterCallback::onFilterStatus(int status) {
+    if (mFilterClientCallback != NULL) {
+        mFilterClientCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
+        return Status::ok();
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
+}
+
 /////////////// FilterClient Helper Methods ///////////////////////
 
 Result FilterClient::getFilterMq() {
diff --git a/media/jni/tuner/FilterClient.h b/media/jni/tuner/FilterClient.h
index 976b2f5..57efcd3 100644
--- a/media/jni/tuner/FilterClient.h
+++ b/media/jni/tuner/FilterClient.h
@@ -17,15 +17,19 @@
 #ifndef _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
 #define _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
 
-//#include <aidl/android/media/tv/tuner/ITunerFilter.h>
+#include <aidl/android/media/tv/tuner/ITunerFilter.h>
+#include <aidl/android/media/tv/tuner/BnTunerFilterCallback.h>
 #include <android/hardware/tv/tuner/1.1/IFilter.h>
 #include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 #include <fmq/MessageQueue.h>
 
+#include "ClientHelper.h"
 #include "FilterClientCallback.h"
 
-//using ::aidl::android::media::tv::tuner::ITunerFilter;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerFilterCallback;
+using ::aidl::android::media::tv::tuner::ITunerFilter;
 
 using ::android::hardware::EventFlag;
 using ::android::hardware::MessageQueue;
@@ -51,18 +55,16 @@
     uint64_t size;
 };
 
-// TODO: pending aidl interface
-/*class TunerFilterCallback : public BnTunerFilterCallback {
+class TunerFilterCallback : public BnTunerFilterCallback {
 
 public:
     TunerFilterCallback(sp<FilterClientCallback> filterClientCallback);
-
-    Status onFilterEvent(vector<TunerDemuxFilterEvent> events);
+    // TODO: complete TunerFilterCallback
     Status onFilterStatus(int status);
 
 private:
     sp<FilterClientCallback> mFilterClientCallback;
-};*/
+};
 
 struct HidlFilterCallback : public IFilterCallback {
 
@@ -80,8 +82,7 @@
 struct FilterClient : public RefBase {
 
 public:
-    // TODO: pending aidl interface
-    FilterClient(DemuxFilterType type);
+    FilterClient(DemuxFilterType type, shared_ptr<ITunerFilter> tunerFilter);
     ~FilterClient();
 
     // TODO: remove after migration to Tuner Service is done.
@@ -179,8 +180,7 @@
      * An AIDL Tuner Filter Singleton assigned at the first time when the Tuner Client
      * opens a filter. Default null when Tuner Service does not exist.
      */
-    // TODO: pending on aidl interface
-    //shared_ptr<ITunerFilter> mTunerFilter;
+    shared_ptr<ITunerFilter> mTunerFilter;
 
     /**
      * A 1.0 Filter HAL interface that is ready before migrating to the TunerFilter.
@@ -200,7 +200,6 @@
     EventFlag* mFilterMQEventFlag;
 
     sp<FilterClientCallback> mCallback;
-    //shared_ptr<TunerFilterCallback> mAidlCallback;
     sp<HidlFilterCallback> mHidlCallback;
 
     native_handle_t* mAvSharedHandle;
diff --git a/media/jni/tuner/FrontendClient.cpp b/media/jni/tuner/FrontendClient.cpp
index d6d64f6..ef8f57f 100644
--- a/media/jni/tuner/FrontendClient.cpp
+++ b/media/jni/tuner/FrontendClient.cpp
@@ -89,9 +89,8 @@
         // TODO: parse hidl settings to aidl settings
         // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
         TunerFrontendSettings settings;
-        // TODO: handle error message.
-        mTunerFrontend->tune(settings);
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->tune(settings);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     Result result;
@@ -110,9 +109,8 @@
 
 Result FrontendClient::stopTune() {
     if (mTunerFrontend != NULL) {
-        // TODO: handle error message.
-        mTunerFrontend->stopTune();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->stopTune();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
@@ -129,9 +127,8 @@
         // TODO: parse hidl settings to aidl settings
         // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
         TunerFrontendSettings settings;
-        // TODO: handle error message.
-        mTunerFrontend->scan(settings, (int)type);
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->scan(settings, (int)type);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     Result result;
@@ -150,9 +147,8 @@
 
 Result FrontendClient::stopScan() {
     if (mTunerFrontend != NULL) {
-        // TODO: handle error message.
-        mTunerFrontend->stopScan();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->stopScan();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
@@ -284,8 +280,8 @@
 Result FrontendClient::close() {
     if (mTunerFrontend != NULL) {
         // TODO: handle error message.
-        mTunerFrontend->close();
-        return Result::SUCCESS;
+        Status s = mTunerFrontend->close();
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mFrontend != NULL) {
diff --git a/media/jni/tuner/FrontendClient.h b/media/jni/tuner/FrontendClient.h
index 4f95c22..03ebb87 100644
--- a/media/jni/tuner/FrontendClient.h
+++ b/media/jni/tuner/FrontendClient.h
@@ -23,6 +23,7 @@
 #include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "FrontendClientCallback.h"
 #include "LnbClient.h"
 
diff --git a/media/jni/tuner/LnbClient.cpp b/media/jni/tuner/LnbClient.cpp
index 77583b8..8d08c25 100644
--- a/media/jni/tuner/LnbClient.cpp
+++ b/media/jni/tuner/LnbClient.cpp
@@ -19,7 +19,6 @@
 #include <android-base/logging.h>
 #include <utils/Log.h>
 
-#include "TunerClient.h"
 #include "LnbClient.h"
 
 using ::android::hardware::tv::tuner::V1_0::Result;
@@ -48,17 +47,21 @@
     if (mTunerLnb != NULL) {
         mAidlCallback = ::ndk::SharedRefBase::make<TunerLnbCallback>(cb);
         Status s = mTunerLnb->setCallback(mAidlCallback);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
-    mHidlCallback = new HidlLnbCallback(cb);
-    return mLnb->setCallback(mHidlCallback);
+    if (mLnb != NULL) {
+        mHidlCallback = new HidlLnbCallback(cb);
+        return mLnb->setCallback(mHidlCallback);
+    }
+
+    return Result::INVALID_STATE;
 }
 
 Result LnbClient::setVoltage(LnbVoltage voltage) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setVoltage((int)voltage);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -71,7 +74,7 @@
 Result LnbClient::setTone(LnbTone tone) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setTone((int)tone);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -84,7 +87,7 @@
 Result LnbClient::setSatellitePosition(LnbPosition position) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->setSatellitePosition((int)position);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -97,7 +100,7 @@
 Result LnbClient::sendDiseqcMessage(vector<uint8_t> diseqcMessage) {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->sendDiseqcMessage(diseqcMessage);
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
@@ -110,7 +113,7 @@
 Result LnbClient::close() {
     if (mTunerLnb != NULL) {
         Status s = mTunerLnb->close();
-        return TunerClient::getServiceSpecificErrorCode(s);
+        return ClientHelper::getServiceSpecificErrorCode(s);
     }
 
     if (mLnb != NULL) {
diff --git a/media/jni/tuner/LnbClient.h b/media/jni/tuner/LnbClient.h
index 2465120..e7869e8 100644
--- a/media/jni/tuner/LnbClient.h
+++ b/media/jni/tuner/LnbClient.h
@@ -23,6 +23,7 @@
 #include <android/hardware/tv/tuner/1.0/ILnbCallback.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "LnbClientCallback.h"
 
 using Status = ::ndk::ScopedAStatus;
@@ -45,7 +46,6 @@
 
 namespace android {
 
-// TODO: pending aidl interface
 class TunerLnbCallback : public BnTunerLnbCallback {
 
 public:
diff --git a/media/jni/tuner/TunerClient.cpp b/media/jni/tuner/TunerClient.cpp
index 498ba0e..4498f54 100644
--- a/media/jni/tuner/TunerClient.cpp
+++ b/media/jni/tuner/TunerClient.cpp
@@ -37,7 +37,9 @@
 TunerClient::TunerClient() {
     // Get HIDL Tuner in migration stage.
     getHidlTuner();
-    updateTunerResources();
+    if (mTuner != NULL) {
+        updateTunerResources();
+    }
     // Connect with Tuner Service.
     ::ndk::SpAIBinder binder(AServiceManager_getService("media.tuner"));
     mTunerService = ITunerService::fromBinder(binder);
@@ -45,6 +47,9 @@
     mTunerService = NULL;
     if (mTunerService == NULL) {
         ALOGE("Failed to get tuner service");
+    } else {
+        // TODO: b/178124017 update TRM in TunerService independently.
+        mTunerService->updateTunerResources();
     }
 }
 
@@ -60,10 +65,8 @@
 
     if (mTunerService != NULL) {
         vector<int32_t> v;
-        int aidl_return;
-        Status s = mTunerService->getFrontendIds(&v, &aidl_return);
-        if (!s.isOk() || aidl_return != (int) Result::SUCCESS
-                || v.size() == 0) {
+        Status s = mTunerService->getFrontendIds(&v);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS || v.size() == 0) {
             ids.clear();
             return ids;
         }
@@ -93,18 +96,22 @@
 
 sp<FrontendClient> TunerClient::openFrontend(int frontendHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerFrontend> tunerFrontend;
-        mTunerService->openFrontend(frontendHandle, &tunerFrontend);
-        if (tunerFrontend == NULL) {
+        Status s = mTunerService->openFrontend(frontendHandle, &tunerFrontend);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS
+                || tunerFrontend == NULL) {
             return NULL;
         }
         int id;
-        // TODO: handle error code
-        tunerFrontend->getFrontendId(&id);
+        s = tunerFrontend->getFrontendId(&id);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         TunerFrontendInfo aidlFrontendInfo;
-        // TODO: handle error code
-        mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
     }
 
@@ -130,7 +137,10 @@
     if (mTunerService != NULL) {
         TunerFrontendInfo aidlFrontendInfo;
         // TODO: handle error code
-        mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        Status s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
     }
 
@@ -165,17 +175,18 @@
     return NULL;
 }
 
-sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
+sp<DemuxClient> TunerClient::openDemux(int demuxHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
-        /*shared_ptr<ITunerDemux> tunerDemux;
-        mTunerService->openDemux(demuxHandle, &tunerDemux);
-        return new DemuxClient(tunerDemux);*/
+        shared_ptr<ITunerDemux> tunerDemux;
+        Status s = mTunerService->openDemux(demuxHandle, &tunerDemux);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
+        return new DemuxClient(tunerDemux);
     }
 
     if (mTuner != NULL) {
-        // TODO: pending aidl interface
-        sp<DemuxClient> demuxClient = new DemuxClient();
+        sp<DemuxClient> demuxClient = new DemuxClient(NULL);
         int demuxId;
         sp<IDemux> hidlDemux = openHidlDemux(demuxId);
         if (hidlDemux != NULL) {
@@ -228,15 +239,16 @@
 
 sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerLnb> tunerLnb;
-        mTunerService->openLnb(lnbHandle, &tunerLnb);
+        Status s = mTunerService->openLnb(lnbHandle, &tunerLnb);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new LnbClient(tunerLnb);
     }
 
     if (mTuner != NULL) {
         int id = getResourceIdFromHandle(lnbHandle, LNB);
-        // TODO: pending aidl interface
         sp<LnbClient> lnbClient = new LnbClient(NULL);
         sp<ILnb> hidlLnb = openHidlLnbById(id);
         if (hidlLnb != NULL) {
@@ -251,14 +263,15 @@
 
 sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
     if (mTunerService != NULL) {
-        // TODO: handle error code
         shared_ptr<ITunerLnb> tunerLnb;
-        mTunerService->openLnbByName(lnbName, &tunerLnb);
+        Status s = mTunerService->openLnbByName(lnbName, &tunerLnb);
+        if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
+            return NULL;
+        }
         return new LnbClient(tunerLnb);
     }
 
     if (mTuner != NULL) {
-        // TODO: pending aidl interface
         sp<LnbClient> lnbClient = new LnbClient(NULL);
         LnbId id;
         sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
@@ -408,29 +421,8 @@
     return lnb;
 }
 
-sp<IDescrambler> TunerClient::openHidlDescrambler() {
-    sp<IDescrambler> descrambler;
-    Result res;
-
-    mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
-        res = r;
-        descrambler = descramblerSp;
-    });
-
-    if (res != Result::SUCCESS || descrambler == NULL) {
-        return NULL;
-    }
-
-    return descrambler;
-}
-
 vector<int> TunerClient::getLnbHandles() {
     vector<int> lnbHandles;
-
-    if (mTunerService != NULL) {
-        // TODO: pending hidl interface
-    }
-
     if (mTuner != NULL) {
         Result res;
         vector<LnbId> lnbIds;
@@ -450,6 +442,22 @@
     return lnbHandles;
 }
 
+sp<IDescrambler> TunerClient::openHidlDescrambler() {
+    sp<IDescrambler> descrambler;
+    Result res;
+
+    mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
+        res = r;
+        descrambler = descramblerSp;
+    });
+
+    if (res != Result::SUCCESS || descrambler == NULL) {
+        return NULL;
+    }
+
+    return descrambler;
+}
+
 FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerFrontendInfo aidlFrontendInfo) {
     FrontendInfo hidlFrontendInfo {
         .type = static_cast<FrontendType>(aidlFrontendInfo.type),
diff --git a/media/jni/tuner/TunerClient.h b/media/jni/tuner/TunerClient.h
index 733ee6b..04035e4 100644
--- a/media/jni/tuner/TunerClient.h
+++ b/media/jni/tuner/TunerClient.h
@@ -24,6 +24,7 @@
 #include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <android/hardware/tv/tuner/1.1/types.h>
 
+#include "ClientHelper.h"
 #include "FrontendClient.h"
 #include "DemuxClient.h"
 #include "DescramblerClient.h"
@@ -135,15 +136,6 @@
      */
     int getHalTunerVersion() { return mTunerVersion; }
 
-    static Result getServiceSpecificErrorCode(Status& s) {
-        if (s.getExceptionCode() == EX_SERVICE_SPECIFIC) {
-            return static_cast<Result>(s.getServiceSpecificError());
-        } else if (s.isOk()) {
-            return Result::SUCCESS;
-        }
-        return Result::UNKNOWN_ERROR;
-    }
-
 private:
     sp<ITuner> getHidlTuner();
     sp<IFrontend> openHidlFrontendById(int id);
diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml
index f596b40..d3535d4 100644
--- a/packages/InputDevices/res/values-ta/strings.xml
+++ b/packages/InputDevices/res/values-ta/strings.xml
@@ -2,7 +2,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"உள்ளீட்டுச் சாதனங்கள்"</string>
-    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android விசைப்பலகை"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android கீபோர்டு"</string>
     <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ஆங்கிலம் (யூகே)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ஆங்கிலம் (யூஎஸ்)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ஆங்கிலம் (யூஎஸ்), சர்வதேச நடை"</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 713be54..5da9e97 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -553,6 +553,9 @@
         dumpSetting(s, p,
                 Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM,
                 GlobalSettingsProto.Development.ENABLE_SIZECOMPAT_FREEFORM);
+        dumpSetting(s, p,
+                Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
+                GlobalSettingsProto.Development.ENABLE_NON_RESIZABLE_MULTI_WINDOW);
         p.end(developmentToken);
 
         final long deviceToken = p.start(GlobalSettingsProto.DEVICE);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index edb5506..9de7630 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -297,6 +297,24 @@
         Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency);
     }
 
+    private static final Set<String> sAllSecureSettings = new ArraySet<>();
+    private static final Set<String> sReadableSecureSettings = new ArraySet<>();
+    static {
+        Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings);
+    }
+
+    private static final Set<String> sAllSystemSettings = new ArraySet<>();
+    private static final Set<String> sReadableSystemSettings = new ArraySet<>();
+    static {
+        Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings);
+    }
+
+    private static final Set<String> sAllGlobalSettings = new ArraySet<>();
+    private static final Set<String> sReadableGlobalSettings = new ArraySet<>();
+    static {
+        Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings);
+    }
+
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
@@ -1919,6 +1937,7 @@
         if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
             return;
         }
+        checkReadableAnnotation(settingsType, settingName);
         ApplicationInfo ai = getCallingApplicationInfoOrThrow();
         if (!ai.isInstantApp()) {
             return;
@@ -1932,6 +1951,41 @@
         }
     }
 
+    /**
+     * Check if the target settings key is readable. Reject if the caller app is trying to access a
+     * settings key defined in the Settings.Secure, Settings.System or Settings.Global and is not
+     * annotated as @Readable.
+     * Notice that a key string that is not defined in any of the Settings.* classes will still be
+     * regarded as readable.
+     */
+    private void checkReadableAnnotation(int settingsType, String settingName) {
+        final Set<String> allFields;
+        final Set<String> readableFields;
+        switch (settingsType) {
+            case SETTINGS_TYPE_GLOBAL:
+                allFields = sAllGlobalSettings;
+                readableFields = sReadableGlobalSettings;
+                break;
+            case SETTINGS_TYPE_SYSTEM:
+                allFields = sAllSystemSettings;
+                readableFields = sReadableSystemSettings;
+                break;
+            case SETTINGS_TYPE_SECURE:
+                allFields = sAllSecureSettings;
+                readableFields = sReadableSecureSettings;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid settings type: " + settingsType);
+        }
+
+        if (allFields.contains(settingName) && !readableFields.contains(settingName)) {
+            throw new SecurityException(
+                    "Settings key: <" + settingName + "> is not readable. From S+, new public "
+                            + "settings keys need to be annotated with @Readable unless they are "
+                            + "annotated with @hide.");
+        }
+    }
+
     private ApplicationInfo getCallingApplicationInfoOrThrow() {
         // We always use the callingUid for this lookup. This means that if hypothetically an
         // app was installed in user A with cross user and in user B as an Instant App
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 07a5a44..eaa6885 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -228,6 +228,7 @@
                     Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
                     Settings.Global.DEVELOPMENT_FORCE_RTL,
                     Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM,
+                    Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
                     Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV,
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml
index 21c9051..b844515 100644
--- a/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml
+++ b/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml
@@ -13,8 +13,13 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<vector android:height="36sp" android:viewportHeight="36"
-        android:viewportWidth="36" android:width="36sp" xmlns:android="http://schemas.android.com/apk/res/android">
-    <path android:fillColor="?android:attr/colorAccent" android:pathData="M18,18m-18,0a18,18 0,1 1,36 0a18,18 0,1 1,-36 0"/>
-    <path android:fillColor="?android:attr/textColorPrimaryInverse" android:pathData="M17.59,13.41L21.17,17H7v2h14.17l-3.59,3.59L19,24l6,-6l-6,-6L17.59,13.41zM26,12v12h2V12H26z"/>
-</vector>
\ No newline at end of file
+<vector
+     xmlns:android="http://schemas.android.com/apk/res/android"
+     android:height="36sp"
+     android:viewportHeight="36"
+     android:viewportWidth="36"
+     android:width="36sp">
+  <path android:fillColor="?android:attr/colorBackground"
+        android:pathData="M17.59,13.41L21.17,17H7v2h14.17l-3.59,3.59L19,24l6,-6l-6,-6L17.59,
+                          13.41zM26,12v12h2V12H26z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml b/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
new file mode 100644
index 0000000..b7a9fafd
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* 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.
+*/
+-->
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <solid android:color="?android:attr/colorBackground" />
+  <corners android:radius="10dp" />
+</shape>
diff --git a/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.xml b/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.xml
deleted file mode 100644
index 51c442a..0000000
--- a/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.xml
+++ /dev/null
@@ -1,20 +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
-  -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="?android:attr/colorControlHighlight"
-        android:radius="40dp"/>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_num_pad_key.xml b/packages/SystemUI/res-keyguard/layout/keyguard_num_pad_key.xml
index 72591d46..411fea5 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_num_pad_key.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_num_pad_key.xml
@@ -17,15 +17,18 @@
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
     <TextView
         android:id="@+id/digit_text"
-        style="@style/Widget.TextView.NumPadKey"
+        style="@style/Widget.TextView.NumPadKey.Digit"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         />
+    <!-- b/172360102: Setting visibility to gone for now, in order to see if there are many
+         issues with removing the alpha characters. -->
     <TextView
         android:id="@+id/klondike_text"
         style="@style/Widget.TextView.NumPadKey.Klondike"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:visibility="gone"
         />
 </merge>
 
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 87c98d2..aa14645a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -24,7 +24,6 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
         android:orientation="vertical"
         >
     <LinearLayout
@@ -34,37 +33,34 @@
             android:orientation="vertical"
             android:layout_weight="1"
             android:layoutDirection="ltr"
+            android:layout_marginBottom="8dp"
             >
-        <com.android.keyguard.AlphaOptimizedRelativeLayout
-                android:id="@+id/row0"
-                android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
-                android:paddingBottom="16dp"
-                >
+      <Space
+          android:layout_width="match_parent"
+          android:layout_height="0dp"
+          android:layout_weight="1"
+          />
+      <com.android.keyguard.AlphaOptimizedRelativeLayout
+          android:id="@+id/row0"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:paddingBottom="16dp"
+          >
             <com.android.keyguard.PasswordTextView
                     android:id="@+id/pinEntry"
                     android:layout_width="@dimen/keyguard_security_width"
-                    android:layout_height="match_parent"
+                    android:layout_height="@dimen/keyguard_password_height"
                     style="@style/Widget.TextView.Password"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
                     androidprv:scaledTextSize="@integer/scaled_password_text_size"
                     android:contentDescription="@string/keyguard_accessibility_pin_area"
                     />
-            <View
-                    android:id="@+id/divider"
-                    android:layout_width="match_parent"
-                    android:layout_height="1dp"
-                    android:layout_alignParentBottom="true"
-                    android:background="@drawable/pin_divider"
-                    />
         </com.android.keyguard.AlphaOptimizedRelativeLayout>
         <LinearLayout
                 android:id="@+id/row1"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -95,8 +91,7 @@
         <LinearLayout
                 android:id="@+id/row2"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -127,9 +122,8 @@
         <LinearLayout
                 android:id="@+id/row3"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
-                android:layout_weight="1"
                 >
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key7"
@@ -159,18 +153,16 @@
         <LinearLayout
                 android:id="@+id/row4"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_delete"
-                    style="@style/Keyguard.ImageButton.NumPadDelete"
+                    style="@style/NumPadKey.Delete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -180,13 +172,12 @@
                     androidprv:textView="@+id/pinEntry"
                     androidprv:digit="0"
                     />
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/key_enter"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable_pin"
+                    style="@style/NumPadKey.Enter"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index 912d7bb..64ccefd 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -25,9 +25,14 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
         android:gravity="center_horizontal">
 
+  <Space
+      android:layout_width="match_parent"
+      android:layout_height="0dp"
+      android:layout_weight="1"
+      />
+
     <ImageView
             android:id="@+id/keyguard_sim"
             android:layout_width="match_parent"
@@ -37,10 +42,9 @@
 
     <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="0dp"
+            android:layout_height="wrap_content"
             android:orientation="vertical"
             android:gravity="center"
-            android:layout_weight="1"
             android:layoutDirection="ltr"
             >
         <include layout="@layout/keyguard_esim_area"
@@ -52,32 +56,23 @@
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:paddingBottom="16dp"
                 >
             <com.android.keyguard.PasswordTextView
                     android:id="@+id/simPinEntry"
                     android:layout_width="@dimen/keyguard_security_width"
-                    android:layout_height="match_parent"
+                    android:layout_height="@dimen/keyguard_password_height"
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
                     androidprv:scaledTextSize="@integer/scaled_password_text_size"
                     android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
                     />
-            <View
-                    android:id="@+id/divider"
-                    android:layout_width="match_parent"
-                    android:layout_height="1dp"
-                    android:layout_alignParentBottom="true"
-                    android:background="@drawable/pin_divider"
-                    />
         </RelativeLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -107,8 +102,7 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -138,9 +132,8 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
-                android:layout_weight="1"
                 >
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key7"
@@ -169,18 +162,16 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_delete"
-                    style="@style/Keyguard.ImageButton.NumPadDelete"
+                    style="@style/NumPadKey.Delete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -190,13 +181,12 @@
                     androidprv:textView="@+id/simPinEntry"
                     androidprv:digit="0"
                     />
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/key_enter"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable_pin"
+                    style="@style/NumPadKey.Enter"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index 81b4964..dc77bd3 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -26,9 +26,14 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-        androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
         android:gravity="center_horizontal">
 
+  <Space
+      android:layout_width="match_parent"
+      android:layout_height="0dp"
+      android:layout_weight="1"
+      />
+
     <ImageView
             android:id="@+id/keyguard_sim"
             android:layout_width="match_parent"
@@ -38,7 +43,7 @@
 
     <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="0dp"
+            android:layout_height="wrap_content"
             android:orientation="vertical"
             android:gravity="center"
             android:layout_weight="1"
@@ -53,32 +58,23 @@
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:paddingBottom="16dp"
                 >
             <com.android.keyguard.PasswordTextView
                     android:id="@+id/pukEntry"
                     android:layout_width="@dimen/keyguard_security_width"
-                    android:layout_height="match_parent"
+                    android:layout_height="@dimen/keyguard_password_height"
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
                     androidprv:scaledTextSize="@integer/scaled_password_text_size"
                     android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
                     />
-            <View
-                    android:id="@+id/divider"
-                    android:layout_width="match_parent"
-                    android:layout_height="1dp"
-                    android:layout_alignParentBottom="true"
-                    android:background="@drawable/pin_divider"
-                    />
         </RelativeLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -108,8 +104,7 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
             <com.android.keyguard.NumPadKey
@@ -139,9 +134,8 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
-                android:layout_weight="1"
                 >
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key7"
@@ -170,18 +164,16 @@
         </LinearLayout>
         <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
+                android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 >
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_delete"
-                    style="@style/Keyguard.ImageButton.NumPadDelete"
+                    style="@style/NumPadKey.Delete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -191,13 +183,12 @@
                     androidprv:textView="@+id/pukEntry"
                     androidprv:digit="0"
                     />
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.keyguard.NumPadButton
                     android:id="@+id/key_enter"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable_pin"
+                    style="@style/NumPadKey.Enter"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index bfcc56c..eb7a1f7 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -40,6 +40,8 @@
 
     <attr name="passwordStyle" format="reference" />
 
+    <attr name="numPadKeyStyle" format="reference" />
+
     <declare-styleable name="AnimatableClockView">
         <attr name="dozeWeight" format="integer" />
         <attr name="lockScreenWeight" format="integer" />
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index f9389ce..aa87107 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -33,6 +33,9 @@
          (includes 2x keyguard_security_view_top_margin) -->
     <dimen name="keyguard_security_max_height">450dp</dimen>
 
+    <!-- pin/password field max height -->
+    <dimen name="keyguard_password_height">80dp</dimen>
+
     <!-- Margin around the various security views -->
     <dimen name="keyguard_security_view_top_margin">8dp</dimen>
     <dimen name="keyguard_security_view_lateral_margin">36dp</dimen>
@@ -81,4 +84,7 @@
 
     <!-- The translation for disappearing security views after having solved them. -->
     <dimen name="disappear_y_translation">-32dp</dimen>
+
+    <!-- Spacing around each button used for PIN view -->
+    <dimen name="num_pad_key_margin">2dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 71a1cc2..2e99dea 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -30,7 +30,13 @@
         <item name="android:paddingLeft">12dp</item>
         <item name="android:paddingRight">12dp</item>
     </style>
-    <style name="Widget.TextView.NumPadKey" parent="@android:style/Widget.DeviceDefault.TextView">
+    <style name="NumPadKey" parent="Theme.SystemUI">
+      <item name="android:colorControlNormal">?android:attr/colorBackground</item>
+      <item name="android:colorControlHighlight">?android:attr/colorAccent</item>
+      <item name="android:background">@drawable/num_pad_key_background</item>
+    </style>
+    <style name="Widget.TextView.NumPadKey.Digit"
+           parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:singleLine">true</item>
         <item name="android:gravity">center_horizontal|center_vertical</item>
         <item name="android:background">@null</item>
@@ -38,26 +44,25 @@
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:paddingBottom">-16dp</item>
-        <item name="android:colorControlHighlight">?android:attr/textColorPrimary</item>
     </style>
     <style name="Widget.TextView.Password" parent="@android:style/Widget.TextView">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:gravity">center</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
-    <style name="Keyguard.ImageButton.NumPadDelete" parent="@android:style/Widget.DeviceDefault.ImageButton">
+    <style name="NumPadKey.Delete">
         <item name="android:src">@drawable/ic_backspace_black_24dp</item>
-        <item name="android:paddingBottom">11sp</item>
         <item name="android:tint">?android:attr/textColorSecondary</item>
         <item name="android:tintMode">src_in</item>
-        <item name="android:src">@drawable/ic_backspace_black_24dp</item>
     </style>
-    <style name="Keyguard.ImageButton.NumPadEnter" parent="@android:style/Widget.DeviceDefault.ImageButton">
-        <item name="android:src">@drawable/ic_keyboard_tab_36dp</item>
-        <item name="android:paddingBottom">11sp</item>
+    <style name="NumPadKey.Enter">
+      <item name="android:colorControlNormal">?android:attr/textColorSecondary</item>
+      <item name="android:src">@drawable/ic_keyboard_tab_36dp</item>
     </style>
-    <style name="Widget.TextView.NumPadKey.Klondike">
+    <style name="Widget.TextView.NumPadKey.Klondike"
+           parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">12sp</item>
+        <item name="android:background">@null</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
         <item name="android:textColor">?android:attr/textColorSecondary</item>
         <item name="android:paddingBottom">0dp</item>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_divider.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
similarity index 64%
rename from packages/SystemUI/res-keyguard/drawable/pin_divider.xml
rename to packages/SystemUI/res/drawable/qs_background_primary.xml
index 39104b5..0a3afc5 100644
--- a/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2017 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.
@@ -12,9 +12,11 @@
   ~ distributed under the License is distributed on an "AS IS" BASIS,
   ~ WITHOUT 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.
   -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/pin_divider_color" />
-</shape>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
+    <shape>
+        <solid android:color="?android:attr/colorBackground"/>
+        <corners android:radius="@dimen/notification_corner_radius" />
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 387f2f2..77f1743 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -25,7 +25,8 @@
     <View
         android:id="@+id/quick_settings_background"
         android:layout_width="match_parent"
-        android:layout_height="0dp" />
+        android:layout_height="0dp"
+        android:background="@drawable/qs_background_primary" />
 
     <com.android.systemui.qs.NonInterceptingScrollView
         android:id="@+id/expanded_qs_scroll_view"
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index db8bfec..de2db98 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -20,6 +20,7 @@
 
     <bool name="flag_notification_pipeline2">false</bool>
     <bool name="flag_notification_pipeline2_rendering">false</bool>
+    <bool name="flag_shade_is_opaque">true</bool>
 
     <!-- b/171917882 -->
     <bool name="flag_notification_twocolumn">false</bool>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d706ec2..db260ce 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -319,6 +319,7 @@
         <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
         <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
         <item name="passwordStyle">@style/PasswordTheme</item>
+        <item name="numPadKeyStyle">@style/NumPadKey</item>
         <item name="backgroundProtectedStyle">@style/BackgroundProtectedStyle</item>
         <item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
         <item name="shadowRadius">@dimen/keyguard_shadow_radius</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 4ddfccb2..6a6b964 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -27,10 +27,8 @@
 import android.content.res.ColorStateList;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
 import android.view.View;
-import android.widget.ImageButton;
 
 import com.android.internal.widget.LockscreenCredential;
 import com.android.settingslib.Utils;
@@ -42,10 +40,9 @@
 public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView {
 
     protected PasswordTextView mPasswordEntry;
-    private View mOkButton;
-    private ImageButton mDeleteButton;
+    private NumPadButton mOkButton;
+    private NumPadButton mDeleteButton;
     private NumPadKey[] mButtons = new NumPadKey[10];
-    private View mDivider;
 
     public KeyguardPinBasedInputView(Context context) {
         this(context, null);
@@ -152,7 +149,6 @@
 
         mDeleteButton = findViewById(R.id.delete_button);
         mDeleteButton.setVisibility(View.VISIBLE);
-        mDivider = findViewById(R.id.divider);
 
         mButtons[0] = findViewById(R.id.key0);
         mButtons[1] = findViewById(R.id.key1);
@@ -181,12 +177,9 @@
         int deleteColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
                 .getDefaultColor();
         mDeleteButton.setImageTintList(ColorStateList.valueOf(deleteColor));
-        mDivider.setBackground(getContext().getDrawable(R.drawable.pin_divider));
 
-        ContextThemeWrapper themedContext = new ContextThemeWrapper(mContext,
-                R.style.Widget_TextView_NumPadKey);
-        mDeleteButton.setBackground(themedContext.getDrawable(R.drawable.ripple_drawable_pin));
-        mOkButton.setBackground(themedContext.getDrawable(R.drawable.ripple_drawable_pin));
+        mDeleteButton.reloadColors();
+        mOkButton.reloadColors();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
new file mode 100644
index 0000000..cdf9858
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.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 com.android.keyguard;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.GradientDrawable;
+import android.view.ContextThemeWrapper;
+import android.view.ViewGroup;
+
+import androidx.annotation.StyleRes;
+
+import com.android.internal.graphics.ColorUtils;
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+/**
+ * Provides background color and radius animations for key pad buttons.
+ */
+class NumPadAnimator {
+    private ValueAnimator mAnimator;
+    private GradientDrawable mBackground;
+    private int mMargin;
+    private int mNormalColor;
+    private int mHighlightColor;
+    private int mStyle;
+
+    NumPadAnimator(Context context, final GradientDrawable background, @StyleRes int style) {
+        mBackground = (GradientDrawable) background.mutate();
+        mStyle = style;
+
+        reloadColors(context);
+
+        mMargin = context.getResources().getDimensionPixelSize(R.dimen.num_pad_key_margin);
+
+        // Actual values will be updated later, usually during an onLayout() call
+        mAnimator = ValueAnimator.ofFloat(0f);
+        mAnimator.setDuration(250);
+        mAnimator.setInterpolator(Interpolators.LINEAR);
+        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                public void onAnimationUpdate(ValueAnimator anim) {
+                    mBackground.setCornerRadius((float) anim.getAnimatedValue());
+                    mBackground.setColor(ColorUtils.blendARGB(mHighlightColor, mNormalColor,
+                            anim.getAnimatedFraction()));
+                }
+        });
+
+    }
+
+    void updateMargin(ViewGroup.MarginLayoutParams lp) {
+        lp.setMargins(mMargin, mMargin, mMargin, mMargin);
+    }
+
+    void onLayout(int height) {
+        float startRadius = height / 10f;
+        float endRadius = height / 2f;
+        mBackground.setCornerRadius(endRadius);
+        mAnimator.setFloatValues(startRadius, endRadius);
+    }
+
+    void start() {
+        mAnimator.cancel();
+        mAnimator.start();
+    }
+
+    /**
+     * Reload colors from resources.
+     **/
+    void reloadColors(Context context) {
+        int[] customAttrs = {android.R.attr.colorControlNormal,
+                android.R.attr.colorControlHighlight};
+
+        ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
+        TypedArray a = ctw.obtainStyledAttributes(customAttrs);
+        mNormalColor = a.getColor(0, 0);
+        mHighlightColor = a.getColor(1, 0);
+        a.recycle();
+
+        mBackground.setColor(mNormalColor);
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
new file mode 100644
index 0000000..3728106
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.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.keyguard;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
+
+/**
+ * Similar to the {@link NumPadKey}, but displays an image.
+ */
+public class NumPadButton extends AlphaOptimizedImageButton {
+
+    private final NumPadAnimator mAnimator;
+
+    public NumPadButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mAnimator = new NumPadAnimator(context, (GradientDrawable) getBackground(),
+                attrs.getStyleAttribute());
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        mAnimator.updateMargin((ViewGroup.MarginLayoutParams) getLayoutParams());
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // Set width/height to the same value to ensure a smooth circle for the bg
+        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+
+        mAnimator.onLayout(b - t);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mAnimator.start();
+        return super.onTouchEvent(event);
+    }
+
+    /**
+     * Reload colors from resources.
+     **/
+    public void reloadColors() {
+        mAnimator.reloadColors(getContext());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index a518205..8ebcb20 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -18,11 +18,10 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
 import android.view.HapticFeedbackConstants;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -48,6 +47,8 @@
     private int mTextViewResId;
     private PasswordTextView mTextView;
 
+    private final NumPadAnimator mAnimator;
+
     private View.OnClickListener mListener = new View.OnClickListener() {
         @Override
         public void onClick(View thisView) {
@@ -73,7 +74,7 @@
     }
 
     public NumPadKey(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+        this(context, attrs, R.attr.numPadKeyStyle);
     }
 
     public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
@@ -84,7 +85,8 @@
         super(context, attrs, defStyle);
         setFocusable(true);
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey, defStyle,
+                contentResource);
 
         try {
             mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
@@ -116,20 +118,16 @@
                 final int len = klondike.length();
                 if (len > 0) {
                     mKlondikeText.setText(klondike);
-                } else {
+                } else if (mKlondikeText.getVisibility() != View.GONE) {
                     mKlondikeText.setVisibility(View.INVISIBLE);
                 }
             }
         }
 
-        a = context.obtainStyledAttributes(attrs, android.R.styleable.View);
-        if (!a.hasValueOrEmpty(android.R.styleable.View_background)) {
-            Drawable rippleDrawable = new ContextThemeWrapper(mContext,
-                    R.style.Widget_TextView_NumPadKey).getDrawable(R.drawable.ripple_drawable_pin);
-            setBackground(rippleDrawable);
-        }
-        a.recycle();
         setContentDescription(mDigitText.getText().toString());
+
+        mAnimator = new NumPadAnimator(context, (GradientDrawable) getBackground(),
+                R.style.NumPadKey);
     }
 
     /**
@@ -142,9 +140,8 @@
                 .getDefaultColor();
         mDigitText.setTextColor(textColor);
         mKlondikeText.setTextColor(klondikeColor);
-        Drawable rippleDrawable = new ContextThemeWrapper(mContext,
-                R.style.Widget_TextView_NumPadKey).getDrawable(R.drawable.ripple_drawable_pin);
-        setBackground(rippleDrawable);
+
+        mAnimator.reloadColors(getContext());
     }
 
     @Override
@@ -152,13 +149,21 @@
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
             doHapticKeyClick();
         }
+
+        mAnimator.start();
+
         return super.onTouchEvent(event);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        mAnimator.updateMargin((ViewGroup.MarginLayoutParams) getLayoutParams());
+
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         measureChildren(widthMeasureSpec, heightMeasureSpec);
+
+        // Set width/height to the same value to ensure a smooth circle for the bg
+        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
     }
 
     @Override
@@ -176,6 +181,8 @@
 
         left = centerX - mKlondikeText.getMeasuredWidth() / 2;
         mKlondikeText.layout(left, top, left + mKlondikeText.getMeasuredWidth(), bottom);
+
+        mAnimator.onLayout(b - t);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 16e9590..e8976d3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -67,6 +67,7 @@
 
     private int mSideMargins;
     private boolean mQsDisabled;
+    private boolean mBackgroundVisible;
     private int mContentPadding = -1;
     private boolean mAnimateBottomOnNextLayout;
 
@@ -122,6 +123,14 @@
         return true;
     }
 
+    /**
+     * If QS should have a solid or transparent background.
+     */
+    public void setBackgroundVisible(boolean visible) {
+        mBackgroundVisible = visible;
+        updateBackgroundVisibility();
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // QSPanel will show as many rows as it can (up to TileLayout.MAX_ROWS) such that the
@@ -174,7 +183,11 @@
         final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
         if (disabled == mQsDisabled) return;
         mQsDisabled = disabled;
-        mBackground.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        updateBackgroundVisibility();
+    }
+
+    private void updateBackgroundVisibility() {
+        mBackground.setVisibility(mQsDisabled || !mBackgroundVisible ? GONE : VISIBLE);
     }
 
     void updateResources(QSPanelController qsPanelController,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index dbdd04a..ed308ae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -44,6 +44,7 @@
 import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSFragmentComponent;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
@@ -105,6 +106,7 @@
     private QSPanelController mQSPanelController;
     private QuickQSPanelController mQuickQSPanelController;
     private QSCustomizerController mQSCustomizerController;
+    private FeatureFlags mFeatureFlags;
 
     @Inject
     public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
@@ -112,7 +114,7 @@
             StatusBarStateController statusBarStateController, CommandQueue commandQueue,
             QSDetailDisplayer qsDetailDisplayer, @Named(QS_PANEL) MediaHost qsMediaHost,
             @Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
-            QSFragmentComponent.Factory qsComponentFactory) {
+            QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mInjectionInflater = injectionInflater;
         mCommandQueue = commandQueue;
@@ -122,6 +124,7 @@
         mQsComponentFactory = qsComponentFactory;
         commandQueue.observe(getLifecycle(), this);
         mHost = qsTileHost;
+        mFeatureFlags = featureFlags;
         mStatusBarStateController = statusBarStateController;
     }
 
@@ -163,6 +166,7 @@
         mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
         mQSContainerImplController.init();
         mContainer = mQSContainerImplController.getView();
+        mContainer.setBackgroundVisible(!mFeatureFlags.isShadeOpaque());
 
         mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter);
         mQSAnimator = qsFragmentComponent.getQSAnimator();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index ac3fd4b..2cd367d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -457,6 +457,17 @@
                 if (!addedDefault) {
                     List<String> defaultSpecs = getDefaultSpecs(context);
                     for (String spec : defaultSpecs) {
+                        // TODO(b/174753536): Move it into the config file.
+                        if (FeatureFlagUtils.isEnabled(
+                                context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+                            if (spec.equals("wifi") || spec.equals("cell")) {
+                                continue;
+                            }
+                        } else {
+                            if (spec.equals("internet")) {
+                                continue;
+                            }
+                        }
                         if (!addedSpecs.contains(spec)) {
                             tiles.add(spec);
                             addedSpecs.add(spec);
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 59490c6..7eeb4bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -29,6 +29,7 @@
 import android.service.quicksettings.TileService;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.FeatureFlagUtils;
 import android.widget.Button;
 
 import com.android.systemui.R;
@@ -113,10 +114,26 @@
         }
 
         final ArrayList<QSTile> tilesToAdd = new ArrayList<>();
+        // TODO(b/174753536): Move it into the config file.
+        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+            if (!possibleTiles.contains("internet")) {
+                possibleTiles.add("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`.
             if (spec.startsWith(CustomTile.PREFIX)) continue;
+            // TODO(b/174753536): Move it into the config file.
+            if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+                if (spec.equals("wifi") || spec.equals("cell")) {
+                    continue;
+                }
+            } else {
+                if (spec.equals("internet")) {
+                    continue;
+                }
+            }
             final QSTile tile = host.createTile(spec);
             if (tile == null) {
                 continue;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index a6c3221..1dddc45 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -274,7 +274,8 @@
                         NetworkController.IconState qsIcon, boolean activityIn, boolean activityOut,
                         String description, boolean isTransient, String statusLabel) {
                     // statusIcon.visible has the connected status information
-                    boolean enabledAndConnected = enabled && qsIcon.visible;
+                    boolean enabledAndConnected =
+                            enabled && (qsIcon == null ? false : qsIcon.visible);
                     if (enabledAndConnected != mWifiConnected) {
                         mWifiConnected = enabledAndConnected;
                         // Hotspot is not connected, so changes here should update
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 964c499..d6db736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -44,6 +44,10 @@
         return mFlagReader.isEnabled(R.bool.flag_notification_pipeline2_rendering);
     }
 
+    public boolean isShadeOpaque() {
+        return mFlagReader.isEnabled(R.bool.flag_shade_is_opaque);
+    }
+
     /** b/171917882 */
     public boolean isTwoColumnNotificationShadeEnabled() {
         return mFlagReader.isEnabled(R.bool.flag_notification_twocolumn);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 4a80572..20efa32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -205,30 +205,6 @@
     }
 
     /**
-     * @return whether to clip bottom of given view
-     */
-    private boolean shouldClipBottom(ExpandableView view) {
-        final boolean showShelf = ((ShelfState) getViewState()).hasItemsInStableShelf;
-        if (showShelf) {
-            if (mAmbientState.isShadeOpening()) {
-                final float viewEnd = view.getTranslationY()
-                        + view.getActualHeight()
-                        + mPaddingBetweenElements;
-                final float finalShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
-                // While the shade is opening, only clip view if it overlaps with shelf;
-                // otherwise leave view unclipped.
-                if (viewEnd < finalShelfStart) {
-                    return false;
-                }
-            }
-            // Clip for scrolling.
-            return true;
-        }
-        // Don't clip since we have enough space to show all views.
-        return false;
-    }
-
-    /**
      * Update the shelf appearance based on the other notifications around it. This transforms
      * the icons from the notification area into the shelf.
      */
@@ -369,9 +345,7 @@
         clipTransientViews();
 
         setClipTopAmount(clipTopAmount);
-        boolean isHidden = getViewState().hidden
-                || clipTopAmount >= getIntrinsicHeight()
-                || mAmbientState.isShadeOpening();
+        boolean isHidden = getViewState().hidden || clipTopAmount >= getIntrinsicHeight();
         if (mShowNotificationShelf) {
             setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE);
         }
@@ -494,8 +468,7 @@
         } else {
             shouldClipOwnTop = view.showingPulsing();
         }
-        if (shouldClipBottom(view)
-                && viewEnd > notificationClipEnd && !shouldClipOwnTop
+        if (viewEnd > notificationClipEnd && !shouldClipOwnTop
                 && (mAmbientState.isShadeExpanded() || !isPinned)) {
             int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
             if (isPinned) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 92b381e..ba03d01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -614,12 +614,6 @@
         }
     }
 
-    public void setShouldFadeForShadeOpen(boolean shouldFade) {
-        if (!mViewState.gone) {
-            mViewState.setShouldFadeForShadeOpen(shouldFade);
-        }
-    }
-
     /**
      * @return whether the current view doesn't add height to the overall content. This means that
      * if it is added to a list of items, its content will still have the same height.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index 21b6863..628c4e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -88,12 +88,6 @@
     public boolean hideSensitive;
     public boolean belowSpeedBump;
     public boolean inShelf;
-    public boolean shouldFadeForShadeOpen;
-
-    @Override
-    boolean shouldAnimateAlpha() {
-        return shouldFadeForShadeOpen;
-    }
 
     /**
      * A state indicating whether a headsup is currently fully visible, even when not scrolled.
@@ -177,10 +171,6 @@
         }
     }
 
-    public void setShouldFadeForShadeOpen(boolean shouldFade) {
-        shouldFadeForShadeOpen = shouldFade;
-    }
-
     @Override
     public void animateTo(View child, AnimationProperties properties) {
         super.animateTo(child, properties);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index a2ce9e1..f07d874 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -3947,7 +3947,6 @@
         int numChildren = getChildCount();
         for (int i = 0; i < numChildren; i++) {
             ExpandableView child = (ExpandableView) getChildAt(i);
-            child.setShouldFadeForShadeOpen(mAmbientState.isShadeOpening());
             child.applyViewState();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 4bf7be3..e6efba7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -568,14 +568,11 @@
             // Add padding before sections for overscroll effect.
             childViewState.yTranslation += ambientState.getSectionPadding();
         }
-        boolean show = childViewState.yTranslation < shelfStart
-                && !ambientState.isAppearing();
-        childViewState.hidden = !show
-                && !child.isExpandAnimationRunning()
-                && !child.hasExpandingChild();
-        childViewState.inShelf = !show;
-        childViewState.headsUpIsVisible = show;
-        childViewState.alpha = show ? 1f : 0f;
+        if (childViewState.yTranslation >= shelfStart) {
+            childViewState.hidden = !child.isExpandAnimationRunning() && !child.hasExpandingChild();
+            childViewState.inShelf = true;
+            childViewState.headsUpIsVisible = false;
+        }
     }
 
     protected int getMaxAllowedChildHeight(View child) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 43f1f43..66a48f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -45,7 +45,6 @@
     public static final int ANIMATION_DURATION_CORNER_RADIUS = 200;
     public static final int ANIMATION_DURATION_WAKEUP = 500;
     public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
-    public static final int ANIMATION_DURATION_FADE_IN = 700;
     public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
     public static final int ANIMATION_DURATION_SWIPE = 260;
     public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index abe5c69..3da4e321 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
-import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FADE_IN;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -58,16 +56,6 @@
             return mAnimationFilter;
         }
     };
-
-    protected static final AnimationProperties ANIMATE_ALPHA = new AnimationProperties() {
-        AnimationFilter mAnimationFilter = new AnimationFilter();
-        @Override
-        public AnimationFilter getAnimationFilter() {
-            mAnimationFilter.animateAlpha();
-            return mAnimationFilter;
-        }
-    }.setDuration(ANIMATION_DURATION_FADE_IN);
-
     private static final int TAG_ANIMATOR_TRANSLATION_X = R.id.translation_x_animator_tag;
     private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
     private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
@@ -160,10 +148,6 @@
         scaleY = view.getScaleY();
     }
 
-    boolean shouldAnimateAlpha() {
-        return false;
-    }
-
     /**
      * Applies a {@link ViewState} to a normal view.
      */
@@ -216,26 +200,24 @@
         int oldVisibility = view.getVisibility();
         boolean becomesInvisible = this.alpha == 0.0f
                 || (this.hidden && (!isAnimating(view) || oldVisibility != View.VISIBLE));
-        if (isAnimating(view, TAG_ANIMATOR_ALPHA)) {
-            startAlphaAnimation(view, NO_NEW_ANIMATIONS);
+        boolean animatingAlpha = isAnimating(view, TAG_ANIMATOR_ALPHA);
+        if (animatingAlpha) {
+            updateAlphaAnimation(view);
         } else if (view.getAlpha() != this.alpha) {
-            if (shouldAnimateAlpha()) {
-                startAlphaAnimation(view, ANIMATE_ALPHA);
-            } else {
-                // apply layer type
-                boolean becomesFullyVisible = this.alpha == 1.0f;
-                boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
-                        && view.hasOverlappingRendering();
-                int layerType = view.getLayerType();
-                int newLayerType = newLayerTypeIsHardware
-                        ? View.LAYER_TYPE_HARDWARE
-                        : View.LAYER_TYPE_NONE;
-                if (layerType != newLayerType) {
-                    view.setLayerType(newLayerType, null);
-                }
-                // apply alpha
-                view.setAlpha(this.alpha);
+            // apply layer type
+            boolean becomesFullyVisible = this.alpha == 1.0f;
+            boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
+                    && view.hasOverlappingRendering();
+            int layerType = view.getLayerType();
+            int newLayerType = newLayerTypeIsHardware
+                    ? View.LAYER_TYPE_HARDWARE
+                    : View.LAYER_TYPE_NONE;
+            if (layerType != newLayerType) {
+                view.setLayerType(newLayerType, null);
             }
+
+            // apply alpha
+            view.setAlpha(this.alpha);
         }
 
         // apply visibility
@@ -340,6 +322,10 @@
         }
     }
 
+    private void updateAlphaAnimation(View view) {
+        startAlphaAnimation(view, NO_NEW_ANIMATIONS);
+    }
+
     private void startAlphaAnimation(final View child, AnimationProperties properties) {
         Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
         Float previousEndValue = getChildTag(child,TAG_END_ALPHA);
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 2254ead..b24d0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -896,9 +896,8 @@
             int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
             int clockPreferredY = mKeyguardStatusViewController.getClockPreferredY(totalHeight);
             boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
-            final boolean hasVisibleNotifications = !bypassEnabled
-                    && (mNotificationStackScrollLayoutController.getVisibleNotificationCount() != 0
-                    || mMediaDataManager.hasActiveMedia());
+            final boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
+                    .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
             mKeyguardStatusViewController.setHasVisibleNotifications(hasVisibleNotifications);
             mClockPositionAlgorithm.setup(mStatusBarMinHeight, totalHeight - bottomPadding,
                     mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index fc1811b..1463148 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -49,6 +49,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.BlurUtils;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -125,6 +126,11 @@
      */
     public static final float BUSY_SCRIM_ALPHA = 1f;
 
+    /**
+     * Scrim opacity that can have text on top.
+     */
+    public static final float GAR_SCRIM_ALPHA = 0.6f;
+
     static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
     private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
@@ -199,10 +205,11 @@
             AlarmManager alarmManager, KeyguardStateController keyguardStateController,
             DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
             KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
-            BlurUtils blurUtils, ConfigurationController configurationController) {
+            BlurUtils blurUtils, ConfigurationController configurationController,
+            FeatureFlags featureFlags) {
 
         mScrimStateListener = lightBarController::setScrimState;
-        mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
+        mDefaultScrimAlpha = featureFlags.isShadeOpaque() ? BUSY_SCRIM_ALPHA : GAR_SCRIM_ALPHA;
         mBlurUtils = blurUtils;
 
         mKeyguardStateController = keyguardStateController;
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 e07c3a5..d4a2b41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1730,7 +1730,7 @@
 
         if ((diff2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
             updateQsExpansionEnabled();
-            if ((state1 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
+            if ((state2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
                 mShadeController.animateCollapsePanels();
             }
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index a6b0330..1260eaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -51,6 +51,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.phone.AutoTileManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -87,6 +88,8 @@
     private MediaHost mQSMediaHost;
     @Mock
     private MediaHost mQQSMediaHost;
+    @Mock
+    private FeatureFlags mFeatureFlags;
 
     public QSFragmentTest() {
         super(QSFragment.class);
@@ -175,6 +178,7 @@
                 new QSDetailDisplayer(),
                 mQSMediaHost,
                 mQQSMediaHost,
-                mQsComponentFactory);
+                mQsComponentFactory,
+                mFeatureFlags);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 452ff4a..cfef5be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -38,9 +38,11 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.util.FeatureFlagUtils;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.CollectionUtils;
@@ -62,11 +64,14 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -117,9 +122,16 @@
     private Handler mHandler;
     private TestableLooper mLooper;
     private QSTileHost mQSTileHost;
+    MockitoSession mMockingSession = null;
 
     @Before
     public void setUp() {
+        // TODO(b/174753536): Remove the mMockingSession when
+        // FeatureFlagUtils.SETTINGS_PROVIDER_MODEL is removed.
+        mMockingSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
+                .mockStatic(FeatureFlagUtils.class).startMocking();
+        ExtendedMockito.doReturn(false).when(() -> FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_PROVIDER_MODEL));
         MockitoAnnotations.initMocks(this);
         mLooper = TestableLooper.get(this);
         mHandler = new Handler(mLooper.getLooper());
@@ -132,6 +144,13 @@
                 "", ActivityManager.getCurrentUser());
     }
 
+    @After
+    public void tearDown() throws Exception {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
     private void setUpTileFactory() {
         when(mMockState.toString()).thenReturn(MOCK_STATE_STRING);
         // Only create this kind of tiles
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index a2ffb84..f2f9656b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -45,9 +45,11 @@
 import android.testing.TestableLooper;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.FeatureFlagUtils;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.logging.InstanceId;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -59,6 +61,7 @@
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,6 +71,8 @@
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -113,10 +118,17 @@
     private TileQueryHelper mTileQueryHelper;
     private FakeExecutor mMainExecutor;
     private FakeExecutor mBgExecutor;
+    MockitoSession mMockingSession = null;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        // TODO(b/174753536): Remove the mMockingSession when
+        // FeatureFlagUtils.SETTINGS_PROVIDER_MODEL is removed.
+        mMockingSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
+                .mockStatic(FeatureFlagUtils.class).startMocking();
+        ExtendedMockito.doReturn(false).when(() -> FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_PROVIDER_MODEL));
 
         mContext.setMockPackageManager(mPackageManager);
 
@@ -140,6 +152,13 @@
         mTileQueryHelper.setListener(mListener);
     }
 
+    @After
+    public void tearDown() throws Exception {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
     @Test
     public void testIsFinished_falseBeforeQuerying() {
         assertFalse(mTileQueryHelper.isFinished());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 342b2f5..30c3e6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -50,6 +50,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.BlurUtils;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -104,6 +105,8 @@
     private BlurUtils mBlurUtils;
     @Mock
     private ConfigurationController mConfigurationController;
+    @Mock
+    private FeatureFlags mFeatureFlags;
 
 
     private static class AnimatorListener implements Animator.AnimatorListener {
@@ -211,13 +214,13 @@
         when(mDelayedWakeLockBuilder.setTag(any(String.class)))
                 .thenReturn(mDelayedWakeLockBuilder);
         when(mDelayedWakeLockBuilder.build()).thenReturn(mWakeLock);
-
+        when(mFeatureFlags.isShadeOpaque()).thenReturn(true);
         when(mDockManager.isDocked()).thenReturn(false);
 
         mScrimController = new ScrimController(mLightBarController,
                 mDozeParamenters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
                 new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
-                mDockManager, mBlurUtils, mConfigurationController);
+                mDockManager, mBlurUtils, mConfigurationController, mFeatureFlags);
         mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
         mScrimController.attachViews(mScrimBehind, mScrimInFront, mScrimForBubble);
         mScrimController.setAnimatorListener(mAnimatorListener);
diff --git a/services/api/current.txt b/services/api/current.txt
index 9bbb3ef..17ca369 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -46,6 +46,11 @@
 
 package com.android.server {
 
+  public final class LocalManagerRegistry {
+    method public static <T> void addManager(@NonNull Class<T>, @NonNull T);
+    method @Nullable public static <T> T getManager(@NonNull Class<T>);
+  }
+
   public abstract class SystemService {
     ctor public SystemService(@NonNull android.content.Context);
     method @NonNull public final android.content.Context getContext();
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 7bbbcc0..2f3ad19 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -226,6 +226,8 @@
         "java/com/android/server/connectivity/NetworkRanker.java",
         "java/com/android/server/connectivity/PermissionMonitor.java",
         "java/com/android/server/connectivity/ProxyTracker.java",
+        "java/com/android/server/connectivity/QosCallbackAgentConnection.java",
+        "java/com/android/server/connectivity/QosCallbackTracker.java",
         "java/com/android/server/connectivity/TcpKeepaliveController.java",
         "java/com/android/server/connectivity/Vpn.java",
         "java/com/android/server/connectivity/VpnIkev2Utils.java",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b07e98f..b6232a0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -94,6 +94,7 @@
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkStatsService;
+import android.net.IQosCallback;
 import android.net.ISocketKeepaliveCallback;
 import android.net.InetAddresses;
 import android.net.IpMemoryStore;
@@ -121,6 +122,10 @@
 import android.net.NetworkWatchlistManager;
 import android.net.PrivateDnsConfigParcel;
 import android.net.ProxyInfo;
+import android.net.QosCallbackException;
+import android.net.QosFilter;
+import android.net.QosSocketFilter;
+import android.net.QosSocketInfo;
 import android.net.RouteInfo;
 import android.net.RouteInfoParcel;
 import android.net.SocketKeepalive;
@@ -204,6 +209,7 @@
 import com.android.server.connectivity.NetworkRanker;
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.ProxyTracker;
+import com.android.server.connectivity.QosCallbackTracker;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.BaseNetworkObserver;
 import com.android.server.net.LockdownVpnTracker;
@@ -279,6 +285,10 @@
     // Default to 30s linger time-out. Modifiable only for testing.
     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
+
+    // The maximum number of network request allowed per uid before an exception is thrown.
+    private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
+
     @VisibleForTesting
     protected int mLingerDelayMs;  // Can't be final, or test subclass constructors can't change it.
 
@@ -291,6 +301,8 @@
     @VisibleForTesting
     protected final PermissionMonitor mPermissionMonitor;
 
+    private final PerUidCounter mNetworkRequestCounter;
+
     private KeyStore mKeyStore;
 
     @VisibleForTesting
@@ -614,6 +626,7 @@
     private final LocationPermissionChecker mLocationPermissionChecker;
 
     private KeepaliveTracker mKeepaliveTracker;
+    private QosCallbackTracker mQosCallbackTracker;
     private NetworkNotificationManager mNotifier;
     private LingerMonitor mLingerMonitor;
 
@@ -858,6 +871,66 @@
     };
 
     /**
+     * Keeps track of the number of requests made under different uids.
+     */
+    public static class PerUidCounter {
+        private final int mMaxCountPerUid;
+
+        // Map from UID to number of NetworkRequests that UID has filed.
+        @GuardedBy("mUidToNetworkRequestCount")
+        private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
+
+        /**
+         * Constructor
+         *
+         * @param maxCountPerUid the maximum count per uid allowed
+         */
+        public PerUidCounter(final int maxCountPerUid) {
+            mMaxCountPerUid = maxCountPerUid;
+        }
+
+        /**
+         * Increments the request count of the given uid.  Throws an exception if the number
+         * of open requests for the uid exceeds the value of maxCounterPerUid which is the value
+         * passed into the constructor. see: {@link #PerUidCounter(int)}.
+         *
+         * @throws ServiceSpecificException with
+         * {@link ConnectivityManager.Errors.TOO_MANY_REQUESTS} if the number of requests for
+         * the uid exceed the allowed number.
+         *
+         * @param uid the uid that the request was made under
+         */
+        public void incrementCountOrThrow(final int uid) {
+            synchronized (mUidToNetworkRequestCount) {
+                final int networkRequests = mUidToNetworkRequestCount.get(uid, 0) + 1;
+                if (networkRequests >= mMaxCountPerUid) {
+                    throw new ServiceSpecificException(
+                            ConnectivityManager.Errors.TOO_MANY_REQUESTS);
+                }
+                mUidToNetworkRequestCount.put(uid, networkRequests);
+            }
+        }
+
+        /**
+         * Decrements the request count of the given uid.
+         *
+         * @param uid the uid that the request was made under
+         */
+        public void decrementCount(final int uid) {
+            synchronized (mUidToNetworkRequestCount) {
+                final int requests = mUidToNetworkRequestCount.get(uid, 0);
+                if (requests < 1) {
+                    logwtf("BUG: too small request count " + requests + " for UID " + uid);
+                } else if (requests == 1) {
+                    mUidToNetworkRequestCount.delete(uid);
+                } else {
+                    mUidToNetworkRequestCount.put(uid, requests - 1);
+                }
+            }
+        }
+    }
+
+    /**
      * Dependencies of ConnectivityService, for injection in tests.
      */
     @VisibleForTesting
@@ -945,6 +1018,7 @@
         mSystemProperties = mDeps.getSystemProperties();
         mNetIdManager = mDeps.makeNetIdManager();
         mContext = Objects.requireNonNull(context, "missing Context");
+        mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID);
 
         mMetricsLog = logger;
         mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
@@ -1125,6 +1199,7 @@
 
         mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
         mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
+        mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter);
 
         final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
@@ -2777,6 +2852,7 @@
                         updateCapabilitiesForNetwork(nai);
                         notifyIfacesChangedForNetworkStats();
                     }
+                    break;
                 }
             }
         }
@@ -3338,6 +3414,8 @@
         // of rematchAllNetworksAndRequests
         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
         mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
+
+        mQosCallbackTracker.handleNetworkReleased(nai.network);
         for (String iface : nai.linkProperties.getAllInterfaceNames()) {
             // Disable wakeup packet monitoring for each interface.
             wakeupModifyInterface(iface, nai.networkCapabilities, false);
@@ -3607,7 +3685,7 @@
         nri.unlinkDeathRecipient();
         mNetworkRequests.remove(nri.request);
 
-        decrementNetworkRequestPerUidCount(nri);
+        mNetworkRequestCounter.decrementCount(nri.mUid);
 
         mNetworkRequestInfoLogs.log("RELEASE " + nri);
         if (nri.request.isRequest()) {
@@ -3680,19 +3758,6 @@
         }
     }
 
-    private void decrementNetworkRequestPerUidCount(final NetworkRequestInfo nri) {
-        synchronized (mUidToNetworkRequestCount) {
-            final int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
-            if (requests < 1) {
-                Log.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid);
-            } else if (requests == 1) {
-                mUidToNetworkRequestCount.removeAt(mUidToNetworkRequestCount.indexOfKey(nri.mUid));
-            } else {
-                mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
-            }
-        }
-    }
-
     @Override
     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
         enforceNetworkStackSettingsOrSetup();
@@ -4519,6 +4584,10 @@
         Log.w(TAG, s);
     }
 
+    private static void logwtf(String s) {
+        Log.wtf(TAG, s);
+    }
+
     private static void loge(String s) {
         Log.e(TAG, s);
     }
@@ -5261,11 +5330,6 @@
     private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
 
-    private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
-    // Map from UID to number of NetworkRequests that UID has filed.
-    @GuardedBy("mUidToNetworkRequestCount")
-    private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
-
     private static class NetworkProviderInfo {
         public final String name;
         public final Messenger messenger;
@@ -5379,7 +5443,7 @@
             mBinder = null;
             mPid = getCallingPid();
             mUid = mDeps.getCallingUid();
-            enforceRequestCountLimit();
+            mNetworkRequestCounter.incrementCountOrThrow(mUid);
         }
 
         NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
@@ -5392,7 +5456,7 @@
             mPid = getCallingPid();
             mUid = mDeps.getCallingUid();
             mPendingIntent = null;
-            enforceRequestCountLimit();
+            mNetworkRequestCounter.incrementCountOrThrow(mUid);
 
             try {
                 mBinder.linkToDeath(this, 0);
@@ -5429,17 +5493,6 @@
             return null;
         }
 
-        private void enforceRequestCountLimit() {
-            synchronized (mUidToNetworkRequestCount) {
-                int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
-                if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
-                    throw new ServiceSpecificException(
-                            ConnectivityManager.Errors.TOO_MANY_REQUESTS);
-                }
-                mUidToNetworkRequestCount.put(mUid, networkRequests);
-            }
-        }
-
         void unlinkDeathRecipient() {
             if (mBinder != null) {
                 mBinder.unlinkToDeath(this, 0);
@@ -5661,9 +5714,14 @@
             // Policy already enforced.
             return;
         }
-        if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
-            // If UID is restricted, don't allow them to bring up metered APNs.
-            networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) {
+                // If UID is restricted, don't allow them to bring up metered APNs.
+                networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -5998,7 +6056,7 @@
         final NetworkAgentInfo nai = new NetworkAgentInfo(na,
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
                 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
-                this, mNetd, mDnsResolver, mNMS, providerId, uid);
+                this, mNetd, mDnsResolver, mNMS, providerId, uid, mQosCallbackTracker);
 
         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
         processCapabilitiesFromAgent(nai, nc);
@@ -8278,7 +8336,7 @@
             // Decrement the reference count for this NetworkRequestInfo. The reference count is
             // incremented when the NetworkRequestInfo is created as part of
             // enforceRequestCountLimit().
-            decrementNetworkRequestPerUidCount(nri);
+            mNetworkRequestCounter.decrementCount(nri.mUid);
             return;
         }
 
@@ -8344,7 +8402,7 @@
         // Decrement the reference count for this NetworkRequestInfo. The reference count is
         // incremented when the NetworkRequestInfo is created as part of
         // enforceRequestCountLimit().
-        decrementNetworkRequestPerUidCount(nri);
+        mNetworkRequestCounter.decrementCount(nri.mUid);
 
         iCb.unlinkToDeath(cbInfo, 0);
     }
@@ -8565,7 +8623,7 @@
         private final INetworkManagementService mNMS;
 
         LegacyNetworkActivityTracker(@NonNull Context context,
-                        @NonNull INetworkManagementService nms) {
+                @NonNull INetworkManagementService nms) {
             mContext = context;
             mNMS = nms;
             try {
@@ -8584,7 +8642,7 @@
                         sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active,
                                 tsNanos);
                     }
-        };
+                };
 
         // This is deprecated and only to support legacy use cases.
         private int transportTypeToLegacyType(int type) {
@@ -8694,4 +8752,53 @@
             }
         }
     }
+    /**
+     * Registers {@link QosSocketFilter} with {@link IQosCallback}.
+     *
+     * @param socketInfo the socket information
+     * @param callback the callback to register
+     */
+    @Override
+    public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo,
+            @NonNull final IQosCallback callback) {
+        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork());
+        if (nai == null || nai.networkCapabilities == null) {
+            try {
+                callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
+            } catch (final RemoteException ex) {
+                loge("registerQosCallbackInternal: RemoteException", ex);
+            }
+            return;
+        }
+        registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai);
+    }
+
+    /**
+     * Register a {@link IQosCallback} with base {@link QosFilter}.
+     *
+     * @param filter the filter to register
+     * @param callback the callback to register
+     * @param nai the agent information related to the filter's network
+     */
+    @VisibleForTesting
+    public void registerQosCallbackInternal(@NonNull final QosFilter filter,
+            @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) {
+        if (filter == null) throw new IllegalArgumentException("filter must be non-null");
+        if (callback == null) throw new IllegalArgumentException("callback must be non-null");
+
+        if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
+            enforceConnectivityRestrictedNetworksPermission();
+        }
+        mQosCallbackTracker.registerCallback(callback, filter, nai);
+    }
+
+    /**
+     * Unregisters the given callback.
+     *
+     * @param callback the callback to unregister
+     */
+    @Override
+    public void unregisterQosCallback(@NonNull final IQosCallback callback) {
+        mQosCallbackTracker.unregisterCallback(callback);
+    }
 }
diff --git a/services/core/java/com/android/server/LocalManagerRegistry.java b/services/core/java/com/android/server/LocalManagerRegistry.java
new file mode 100644
index 0000000..85795ff
--- /dev/null
+++ b/services/core/java/com/android/server/LocalManagerRegistry.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.util.ArrayMap;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * The registry for in-process module interfaces.
+ * <p>
+ * In-process module interfaces should be named with the suffix {@code ManagerLocal} for
+ * consistency.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public final class LocalManagerRegistry {
+    private LocalManagerRegistry() {}
+
+    @NonNull
+    private static final Map<Class<?>, Object> sManagers = new ArrayMap<>();
+
+    /**
+     * Get a manager from the registry.
+     *
+     * @param managerClass the class that the manager implements
+     * @return the manager, or {@code null} if not found
+     */
+    @Nullable
+    @SuppressWarnings("unchecked")
+    public static <T> T getManager(@NonNull Class<T> managerClass) {
+        synchronized (sManagers) {
+            return (T) sManagers.get(managerClass);
+        }
+    }
+
+    /**
+     * Adds a manager to the registry.
+     *
+     * @param managerClass the class that the manager implements
+     * @param manager the manager
+     * @throws IllegalStateException if the manager class is already registered
+     */
+    public static <T> void addManager(@NonNull Class<T> managerClass, @NonNull T manager) {
+        Objects.requireNonNull(managerClass, "managerClass");
+        Objects.requireNonNull(manager, "manager");
+        synchronized (sManagers) {
+            if (sManagers.containsKey(managerClass)) {
+                throw new IllegalStateException(managerClass.getName() + " is already registered");
+            }
+            sManagers.put(managerClass, manager);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 2fdc796..76db019 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -31,16 +31,19 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -155,6 +158,11 @@
 
     @NonNull private final PersistableBundleUtils.LockingReadWriteHelper mConfigDiskRwHelper;
 
+    @GuardedBy("mLock")
+    @NonNull
+    private final Map<IBinder, PolicyListenerBinderDeath> mRegisteredPolicyListeners =
+            new ArrayMap<>();
+
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) {
         mContext = requireNonNull(context, "Missing context");
@@ -497,19 +505,60 @@
         }
     }
 
+    /** Binder death recipient used to remove a registered policy listener. */
+    private class PolicyListenerBinderDeath implements Binder.DeathRecipient {
+        @NonNull private final IVcnUnderlyingNetworkPolicyListener mListener;
+
+        PolicyListenerBinderDeath(@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
+            mListener = listener;
+        }
+
+        @Override
+        public void binderDied() {
+            Log.e(TAG, "app died without removing VcnUnderlyingNetworkPolicyListener");
+            removeVcnUnderlyingNetworkPolicyListener(mListener);
+        }
+    }
+
     /** Adds the provided listener for receiving VcnUnderlyingNetworkPolicy updates. */
+    @GuardedBy("mLock")
     @Override
     public void addVcnUnderlyingNetworkPolicyListener(
-            IVcnUnderlyingNetworkPolicyListener listener) {
-        // TODO(b/175739863): implement policy listener registration
-        throw new UnsupportedOperationException("Not yet implemented");
+            @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
+        requireNonNull(listener, "listener was null");
+
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.NETWORK_FACTORY,
+                "Must have permission NETWORK_FACTORY to register a policy listener");
+
+        PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener);
+
+        synchronized (mLock) {
+            mRegisteredPolicyListeners.put(listener.asBinder(), listenerBinderDeath);
+
+            try {
+                listener.asBinder().linkToDeath(listenerBinderDeath, 0 /* flags */);
+            } catch (RemoteException e) {
+                // Remote binder already died - cleanup registered Listener
+                listenerBinderDeath.binderDied();
+            }
+        }
     }
 
     /** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
+    @GuardedBy("mLock")
     @Override
     public void removeVcnUnderlyingNetworkPolicyListener(
-            IVcnUnderlyingNetworkPolicyListener listener) {
-        // TODO(b/175739863): implement policy listener unregistration
-        throw new UnsupportedOperationException("Not yet implemented");
+            @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
+        requireNonNull(listener, "listener was null");
+
+        synchronized (mLock) {
+            PolicyListenerBinderDeath listenerBinderDeath =
+                    mRegisteredPolicyListeners.remove(listener.asBinder());
+
+            if (listenerBinderDeath != null) {
+                listener.asBinder().unlinkToDeath(listenerBinderDeath, 0 /* flags */);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index fcb32a1..e476ca9 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -5373,7 +5373,7 @@
             for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
                 final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i);
                 if (pr.uid == callingUid) {
-                    if (pr.getWindowProcessController().areBackgroundActivityStartsAllowed()) {
+                    if (pr.getWindowProcessController().areBackgroundFgsStartsAllowed()) {
                         ret = FGS_FEATURE_ALLOWED_BY_ACTIVITY_STARTER;
                         break;
                     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f72c9fb..df90a40 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2535,11 +2535,8 @@
             Slog.d(TAG_SWITCH, "updateActivityUsageStats: comp="
                     + activity + " hash=" + appToken.hashCode() + " event=" + event);
         }
-        synchronized (this) {
-            if (mUsageStatsService != null) {
-                mUsageStatsService.reportEvent(activity, userId, event, appToken.hashCode(),
-                        taskRoot);
-            }
+        if (mUsageStatsService != null) {
+            mUsageStatsService.reportEvent(activity, userId, event, appToken.hashCode(), taskRoot);
         }
         if (mContentCaptureService != null && (event == Event.ACTIVITY_PAUSED
                 || event == Event.ACTIVITY_RESUMED || event == Event.ACTIVITY_STOPPED
@@ -2559,10 +2556,8 @@
             Slog.d(TAG_SWITCH, "updateActivityUsageStats: package="
                     + packageName + " event=" + event);
         }
-        synchronized (this) {
-            if (mUsageStatsService != null) {
-                mUsageStatsService.reportEvent(packageName, userId, event);
-            }
+        if (mUsageStatsService != null) {
+            mUsageStatsService.reportEvent(packageName, userId, event);
         }
     }
 
@@ -2577,12 +2572,10 @@
             Slog.d(TAG_SWITCH, "updateForegroundServiceUsageStats: comp="
                     + service + " started=" + started);
         }
-        synchronized (this) {
-            if (mUsageStatsService != null) {
-                mUsageStatsService.reportEvent(service, userId,
-                        started ? UsageEvents.Event.FOREGROUND_SERVICE_START
-                                : UsageEvents.Event.FOREGROUND_SERVICE_STOP, 0, null);
-            }
+        if (mUsageStatsService != null) {
+            mUsageStatsService.reportEvent(service, userId,
+                    started ? UsageEvents.Event.FOREGROUND_SERVICE_START
+                            : UsageEvents.Event.FOREGROUND_SERVICE_STOP, 0, null);
         }
     }
 
@@ -6100,7 +6093,7 @@
         return pfd;
     }
 
-    void reportGlobalUsageEventLocked(int event) {
+    void reportGlobalUsageEvent(int event) {
         final int currentUserId = mUserController.getCurrentUserId();
         mUsageStatsService.reportEvent(Event.DEVICE_EVENT_PACKAGE_NAME, currentUserId, event);
         int[] profiles = mUserController.getCurrentProfileIds();
@@ -6114,8 +6107,8 @@
         }
     }
 
-    void reportCurWakefulnessUsageEventLocked() {
-        reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
+    void reportCurWakefulnessUsageEvent() {
+        reportGlobalUsageEvent(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
                 ? UsageEvents.Event.SCREEN_INTERACTIVE
                 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
     }
@@ -6129,7 +6122,7 @@
             if (wasAwake != isAwake) {
                 // Also update state in a special way for running foreground services UI.
                 mServices.updateScreenStateLocked(isAwake);
-                reportCurWakefulnessUsageEventLocked();
+                reportCurWakefulnessUsageEvent();
                 mActivityTaskManager.onScreenAwakeChanged(isAwake);
                 mOomAdjProfiler.onWakefulnessChanged(wakefulness);
             }
@@ -16529,11 +16522,9 @@
         }
 
         public void reportCurKeyguardUsageEvent(boolean keyguardShowing) {
-            synchronized(ActivityManagerService.this) {
-                ActivityManagerService.this.reportGlobalUsageEventLocked(keyguardShowing
-                        ? UsageEvents.Event.KEYGUARD_SHOWN
-                        : UsageEvents.Event.KEYGUARD_HIDDEN);
-            }
+            ActivityManagerService.this.reportGlobalUsageEvent(keyguardShowing
+                    ? UsageEvents.Event.KEYGUARD_SHOWN
+                    : UsageEvents.Event.KEYGUARD_HIDDEN);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index ffe1d68..3bbc837 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -3046,15 +3046,11 @@
         }
 
         void reportGlobalUsageEventLocked(int event) {
-            synchronized (mService) {
-                mService.reportGlobalUsageEventLocked(event);
-            }
+            mService.reportGlobalUsageEvent(event);
         }
 
         void reportCurWakefulnessUsageEvent() {
-            synchronized (mService) {
-                mService.reportCurWakefulnessUsageEventLocked();
-            }
+            mService.reportCurWakefulnessUsageEvent();
         }
 
         void taskSupervisorRemoveUser(@UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 26f5c4c..9aea7c4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -154,6 +154,8 @@
 
         mPreferredDeviceforComm = null;
         initCommunicationStrategyId();
+
+        mSystemServer.registerUserStartedReceiver(mContext);
     }
 
     /*package*/ Context getContext() {
@@ -993,6 +995,10 @@
         }
     }
 
+    /*package*/ void broadcastStickyIntentToCurrentProfileGroup(Intent intent) {
+        mSystemServer.broadcastStickyIntentToCurrentProfileGroup(intent);
+    }
+
     /*package*/ void dump(PrintWriter pw, String prefix) {
         if (mBrokerHandler != null) {
             pw.println(prefix + "Message handler (watch for unhandled messages):");
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 82586b8..076cbff 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -16,7 +16,6 @@
 package com.android.server.audio;
 
 import android.annotation.NonNull;
-import android.app.ActivityManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -37,7 +36,6 @@
 import android.os.Binder;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -1270,7 +1268,7 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_CURRENT);
+            mDeviceBroker.broadcastStickyIntentToCurrentProfileGroup(intent);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index aa8a651..c94b48c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5591,7 +5591,9 @@
                 profile, suppressNoisyIntent, a2dpVolume);
     }
 
-    /*package*/ void setMusicMute(boolean mute) {
+    /** only public for mocking/spying, do not call outside of AudioService */
+    @VisibleForTesting
+    public void setMusicMute(boolean mute) {
         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
     }
 
@@ -7071,7 +7073,9 @@
         }
     }
 
-    /*package*/ void checkMusicActive(int deviceType, String caller) {
+    /** only public for mocking/spying, do not call outside of AudioService */
+    @VisibleForTesting
+    public void checkMusicActive(int deviceType, String caller) {
         if (mSafeMediaVolumeDevices.contains(deviceType)) {
             sendMsg(mAudioHandler,
                     MSG_CHECK_MUSIC_ACTIVE,
diff --git a/services/core/java/com/android/server/audio/SystemServerAdapter.java b/services/core/java/com/android/server/audio/SystemServerAdapter.java
index 68893f8..22456bc 100644
--- a/services/core/java/com/android/server/audio/SystemServerAdapter.java
+++ b/services/core/java/com/android/server/audio/SystemServerAdapter.java
@@ -18,11 +18,20 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
 import android.media.AudioManager;
 import android.os.Binder;
 import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
 
 import java.util.Objects;
 
@@ -82,4 +91,58 @@
             Binder.restoreCallingIdentity(ident);
         }
     }
+
+    /**
+     * Send sticky broadcast to current user's profile group (including current user)
+     */
+    @VisibleForTesting
+    public void broadcastStickyIntentToCurrentProfileGroup(Intent intent) {
+        int[] profileIds = LocalServices.getService(
+                ActivityManagerInternal.class).getCurrentProfileIds();
+        for (int userId : profileIds) {
+            ActivityManager.broadcastStickyIntent(intent, userId);
+        }
+    }
+
+    /**
+     * Broadcast sticky intents when a profile is started. This is needed because newly created
+     * profiles would not receive the intents until the next state change.
+     */
+    /*package*/ void registerUserStartedReceiver(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_STARTED);
+        context.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                            UserHandle.USER_NULL);
+                    if (userId == UserHandle.USER_NULL) {
+                        return;
+                    }
+
+                    UserManager userManager = context.getSystemService(UserManager.class);
+                    final UserInfo profileParent = userManager.getProfileParent(userId);
+                    if (profileParent == null) {
+                        return;
+                    }
+
+                    // get sticky intents from parent and broadcast them to the started profile
+                    broadcastProfileParentStickyIntent(context, AudioManager.ACTION_HDMI_AUDIO_PLUG,
+                            userId, profileParent.id);
+                    broadcastProfileParentStickyIntent(context, AudioManager.ACTION_HEADSET_PLUG,
+                            userId, profileParent.id);
+                }
+            }
+        }, UserHandle.ALL, filter, null, null);
+    }
+
+    private void broadcastProfileParentStickyIntent(Context context, String intentAction,
+            int profileId, int parentId) {
+        Intent intent = context.registerReceiverAsUser(/*receiver*/ null, UserHandle.of(parentId),
+                new IntentFilter(intentAction), /*broadcastPermission*/ null, /*scheduler*/ null);
+        if (intent != null) {
+            ActivityManager.broadcastStickyIntent(intent, profileId);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index e3663ba..ab0360b 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -36,12 +36,17 @@
 import android.net.NetworkMonitorManager;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
+import android.net.QosCallbackException;
+import android.net.QosFilter;
+import android.net.QosFilterParcelable;
+import android.net.QosSession;
 import android.net.TcpKeepalivePacketData;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.telephony.data.EpsBearerQosSessionAttributes;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -321,18 +326,20 @@
     private final ConnectivityService mConnService;
     private final Context mContext;
     private final Handler mHandler;
+    private final QosCallbackTracker mQosCallbackTracker;
 
     public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
             LinkProperties lp, NetworkCapabilities nc, int score, Context context,
             Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
             IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
-            int creatorUid) {
+            int creatorUid, QosCallbackTracker qosCallbackTracker) {
         Objects.requireNonNull(net);
         Objects.requireNonNull(info);
         Objects.requireNonNull(lp);
         Objects.requireNonNull(nc);
         Objects.requireNonNull(context);
         Objects.requireNonNull(config);
+        Objects.requireNonNull(qosCallbackTracker);
         networkAgent = na;
         network = net;
         networkInfo = info;
@@ -346,6 +353,7 @@
         networkAgentConfig = config;
         this.factorySerialNumber = factorySerialNumber;
         this.creatorUid = creatorUid;
+        mQosCallbackTracker = qosCallbackTracker;
     }
 
     private class AgentDeathMonitor implements IBinder.DeathRecipient {
@@ -531,6 +539,31 @@
         }
     }
 
+    /**
+     * Notify the NetworkAgent that the qos filter should be registered against the given qos
+     * callback id.
+     */
+    public void onQosFilterCallbackRegistered(final int qosCallbackId,
+            final QosFilter qosFilter) {
+        try {
+            networkAgent.onQosFilterCallbackRegistered(qosCallbackId,
+                    new QosFilterParcelable(qosFilter));
+        } catch (final RemoteException e) {
+            Log.e(TAG, "Error registering a qos callback id against a qos filter", e);
+        }
+    }
+
+    /**
+     * Notify the NetworkAgent that the given qos callback id should be unregistered.
+     */
+    public void onQosCallbackUnregistered(final int qosCallbackId) {
+        try {
+            networkAgent.onQosCallbackUnregistered(qosCallbackId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error unregistering a qos callback id", e);
+        }
+    }
+
     // TODO: consider moving out of NetworkAgentInfo into its own class
     private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub {
         private final Handler mHandler;
@@ -584,6 +617,23 @@
             mHandler.obtainMessage(NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED,
                     new Pair<>(NetworkAgentInfo.this, networks)).sendToTarget();
         }
+
+        @Override
+        public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
+                final EpsBearerQosSessionAttributes attributes) {
+            mQosCallbackTracker.sendEventQosSessionAvailable(qosCallbackId, session, attributes);
+        }
+
+        @Override
+        public void sendQosSessionLost(final int qosCallbackId, final QosSession session) {
+            mQosCallbackTracker.sendEventQosSessionLost(qosCallbackId, session);
+        }
+
+        @Override
+        public void sendQosCallbackError(final int qosCallbackId,
+                @QosCallbackException.ExceptionType final int exceptionType) {
+            mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
new file mode 100644
index 0000000..816bf2b
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/QosCallbackAgentConnection.java
@@ -0,0 +1,192 @@
+/*
+ * 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.connectivity;
+
+import static android.net.QosCallbackException.EX_TYPE_FILTER_NONE;
+
+import android.annotation.NonNull;
+import android.net.IQosCallback;
+import android.net.Network;
+import android.net.QosCallbackException;
+import android.net.QosFilter;
+import android.net.QosSession;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.util.Slog;
+
+import java.util.Objects;
+
+/**
+ * Wraps callback related information and sends messages between network agent and the application.
+ * <p/>
+ * This is a satellite class of {@link com.android.server.ConnectivityService} and not meant
+ * to be used in other contexts.
+ *
+ * @hide
+ */
+class QosCallbackAgentConnection implements IBinder.DeathRecipient {
+    private static final String TAG = QosCallbackAgentConnection.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    private final int mAgentCallbackId;
+    @NonNull private final QosCallbackTracker mQosCallbackTracker;
+    @NonNull private final IQosCallback mCallback;
+    @NonNull private final IBinder mBinder;
+    @NonNull private final QosFilter mFilter;
+    @NonNull private final NetworkAgentInfo mNetworkAgentInfo;
+
+    private final int mUid;
+
+    /**
+     * Gets the uid
+     * @return uid
+     */
+    int getUid() {
+        return mUid;
+    }
+
+    /**
+     * Gets the binder
+     * @return binder
+     */
+    @NonNull
+    IBinder getBinder() {
+        return mBinder;
+    }
+
+    /**
+     * Gets the callback id
+     *
+     * @return callback id
+     */
+    int getAgentCallbackId() {
+        return mAgentCallbackId;
+    }
+
+    /**
+     * Gets the network tied to the callback of this connection
+     *
+     * @return network
+     */
+    @NonNull
+    Network getNetwork() {
+        return mFilter.getNetwork();
+    }
+
+    QosCallbackAgentConnection(@NonNull final QosCallbackTracker qosCallbackTracker,
+            final int agentCallbackId,
+            @NonNull final IQosCallback callback,
+            @NonNull final QosFilter filter,
+            final int uid,
+            @NonNull final NetworkAgentInfo networkAgentInfo) {
+        Objects.requireNonNull(qosCallbackTracker, "qosCallbackTracker must be non-null");
+        Objects.requireNonNull(callback, "callback must be non-null");
+        Objects.requireNonNull(filter, "filter must be non-null");
+        Objects.requireNonNull(networkAgentInfo, "networkAgentInfo must be non-null");
+
+        mQosCallbackTracker = qosCallbackTracker;
+        mAgentCallbackId = agentCallbackId;
+        mCallback = callback;
+        mFilter = filter;
+        mUid = uid;
+        mBinder = mCallback.asBinder();
+        mNetworkAgentInfo = networkAgentInfo;
+    }
+
+    @Override
+    public void binderDied() {
+        logw("binderDied: binder died with callback id: " + mAgentCallbackId);
+        mQosCallbackTracker.unregisterCallback(mCallback);
+    }
+
+    void unlinkToDeathRecipient() {
+        mBinder.unlinkToDeath(this, 0);
+    }
+
+    // Returns false if the NetworkAgent was never notified.
+    boolean sendCmdRegisterCallback() {
+        final int exceptionType = mFilter.validate();
+        if (exceptionType != EX_TYPE_FILTER_NONE) {
+            try {
+                if (DBG) log("sendCmdRegisterCallback: filter validation failed");
+                mCallback.onError(exceptionType);
+            } catch (final RemoteException e) {
+                loge("sendCmdRegisterCallback:", e);
+            }
+            return false;
+        }
+
+        try {
+            mBinder.linkToDeath(this, 0);
+        } catch (final RemoteException e) {
+            loge("failed linking to death recipient", e);
+            return false;
+        }
+        mNetworkAgentInfo.onQosFilterCallbackRegistered(mAgentCallbackId, mFilter);
+        return true;
+    }
+
+    void sendCmdUnregisterCallback() {
+        if (DBG) log("sendCmdUnregisterCallback: unregistering");
+        mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
+    }
+
+    void sendEventQosSessionAvailable(final QosSession session,
+            final EpsBearerQosSessionAttributes attributes) {
+        try {
+            if (DBG) log("sendEventQosSessionAvailable: sending...");
+            mCallback.onQosEpsBearerSessionAvailable(session, attributes);
+        } catch (final RemoteException e) {
+            loge("sendEventQosSessionAvailable: remote exception", e);
+        }
+    }
+
+    void sendEventQosSessionLost(@NonNull final QosSession session) {
+        try {
+            if (DBG) log("sendEventQosSessionLost: sending...");
+            mCallback.onQosSessionLost(session);
+        } catch (final RemoteException e) {
+            loge("sendEventQosSessionLost: remote exception", e);
+        }
+    }
+
+    void sendEventQosCallbackError(@QosCallbackException.ExceptionType final int exceptionType) {
+        try {
+            if (DBG) log("sendEventQosCallbackError: sending...");
+            mCallback.onError(exceptionType);
+        } catch (final RemoteException e) {
+            loge("sendEventQosCallbackError: remote exception", e);
+        }
+    }
+
+    private static void log(@NonNull final String msg) {
+        Slog.d(TAG, msg);
+    }
+
+    private static void logw(@NonNull final String msg) {
+        Slog.w(TAG, msg);
+    }
+
+    private static void loge(@NonNull final String msg, final Throwable t) {
+        Slog.e(TAG, msg, t);
+    }
+
+    private static void logwtf(@NonNull final String msg) {
+        Slog.wtf(TAG, msg);
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
new file mode 100644
index 0000000..87b4c16
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
@@ -0,0 +1,277 @@
+/*
+ * 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.connectivity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.IQosCallback;
+import android.net.Network;
+import android.net.QosCallbackException;
+import android.net.QosFilter;
+import android.net.QosSession;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.util.Slog;
+
+import com.android.internal.util.CollectionUtils;
+import com.android.server.ConnectivityService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tracks qos callbacks and handles the communication between the network agent and application.
+ * <p/>
+ * Any method prefixed by handle must be called from the
+ * {@link com.android.server.ConnectivityService} handler thread.
+ *
+ * @hide
+ */
+public class QosCallbackTracker {
+    private static final String TAG = QosCallbackTracker.class.getSimpleName();
+    private static final boolean DBG = true;
+
+    @NonNull
+    private final Handler mConnectivityServiceHandler;
+
+    @NonNull
+    private final ConnectivityService.PerUidCounter mNetworkRequestCounter;
+
+    /**
+     * Each agent gets a unique callback id that is used to proxy messages back to the original
+     * callback.
+     * <p/>
+     * Note: The fact that this is initialized to 0 is to ensure that the thread running
+     * {@link #handleRegisterCallback(IQosCallback, QosFilter, int, NetworkAgentInfo)} sees the
+     * initialized value. This would not necessarily be the case if the value was initialized to
+     * the non-default value.
+     * <p/>
+     * Note: The term previous does not apply to the first callback id that is assigned.
+     */
+    private int mPreviousAgentCallbackId = 0;
+
+    @NonNull
+    private final List<QosCallbackAgentConnection> mConnections = new ArrayList<>();
+
+    /**
+     *
+     * @param connectivityServiceHandler must be the same handler used with
+     *                {@link com.android.server.ConnectivityService}
+     * @param networkRequestCounter keeps track of the number of open requests under a given
+     *                              uid
+     */
+    public QosCallbackTracker(@NonNull final Handler connectivityServiceHandler,
+            final ConnectivityService.PerUidCounter networkRequestCounter) {
+        mConnectivityServiceHandler = connectivityServiceHandler;
+        mNetworkRequestCounter = networkRequestCounter;
+    }
+
+    /**
+     * Registers the callback with the tracker
+     *
+     * @param callback the callback to register
+     * @param filter the filter being registered alongside the callback
+     */
+    public void registerCallback(@NonNull final IQosCallback callback,
+            @NonNull final QosFilter filter, @NonNull final NetworkAgentInfo networkAgentInfo) {
+        final int uid = Binder.getCallingUid();
+
+        // Enforce that the number of requests under this uid has exceeded the allowed number
+        mNetworkRequestCounter.incrementCountOrThrow(uid);
+
+        mConnectivityServiceHandler.post(
+                () -> handleRegisterCallback(callback, filter, uid, networkAgentInfo));
+    }
+
+    private void handleRegisterCallback(@NonNull final IQosCallback callback,
+            @NonNull final QosFilter filter, final int uid,
+            @NonNull final NetworkAgentInfo networkAgentInfo) {
+        final QosCallbackAgentConnection ac =
+                handleRegisterCallbackInternal(callback, filter, uid, networkAgentInfo);
+        if (ac != null) {
+            if (DBG) log("handleRegisterCallback: added callback " + ac.getAgentCallbackId());
+            mConnections.add(ac);
+        } else {
+            mNetworkRequestCounter.decrementCount(uid);
+        }
+    }
+
+    private QosCallbackAgentConnection handleRegisterCallbackInternal(
+            @NonNull final IQosCallback callback,
+            @NonNull final QosFilter filter, final int uid,
+            @NonNull final NetworkAgentInfo networkAgentInfo) {
+        final IBinder binder = callback.asBinder();
+        if (CollectionUtils.any(mConnections, c -> c.getBinder().equals(binder))) {
+            // A duplicate registration would have only made this far due to a programming error.
+            logwtf("handleRegisterCallback: Callbacks can only be register once.");
+            return null;
+        }
+
+        mPreviousAgentCallbackId = mPreviousAgentCallbackId + 1;
+        final int newCallbackId = mPreviousAgentCallbackId;
+
+        final QosCallbackAgentConnection ac =
+                new QosCallbackAgentConnection(this, newCallbackId, callback,
+                        filter, uid, networkAgentInfo);
+
+        final int exceptionType = filter.validate();
+        if (exceptionType != QosCallbackException.EX_TYPE_FILTER_NONE) {
+            ac.sendEventQosCallbackError(exceptionType);
+            return null;
+        }
+
+        // Only add to the callback maps if the NetworkAgent successfully registered it
+        if (!ac.sendCmdRegisterCallback()) {
+            // There was an issue when registering the agent
+            if (DBG) log("handleRegisterCallback: error sending register callback");
+            mNetworkRequestCounter.decrementCount(uid);
+            return null;
+        }
+        return ac;
+    }
+
+    /**
+     * Unregisters callback
+     * @param callback callback to unregister
+     */
+    public void unregisterCallback(@NonNull final IQosCallback callback) {
+        mConnectivityServiceHandler.post(() -> handleUnregisterCallback(callback.asBinder(), true));
+    }
+
+    private void handleUnregisterCallback(@NonNull final IBinder binder,
+            final boolean sendToNetworkAgent) {
+        final QosCallbackAgentConnection agentConnection =
+                CollectionUtils.find(mConnections, c -> c.getBinder().equals(binder));
+        if (agentConnection == null) {
+            logw("handleUnregisterCallback: agentConnection is null");
+            return;
+        }
+
+        if (DBG) {
+            log("handleUnregisterCallback: unregister "
+                    + agentConnection.getAgentCallbackId());
+        }
+
+        mNetworkRequestCounter.decrementCount(agentConnection.getUid());
+        mConnections.remove(agentConnection);
+
+        if (sendToNetworkAgent) {
+            agentConnection.sendCmdUnregisterCallback();
+        }
+        agentConnection.unlinkToDeathRecipient();
+    }
+
+    /**
+     * Called when the NetworkAgent sends the qos session available event
+     *
+     * @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,
+            final QosSession session,
+            final EpsBearerQosSessionAttributes attributes) {
+        runOnAgentConnection(qosCallbackId, "sendEventQosSessionAvailable: ",
+                ac -> ac.sendEventQosSessionAvailable(session, attributes));
+    }
+
+    /**
+     * Called when the NetworkAgent sends the qos session lost event
+     *
+     * @param qosCallbackId the callback id that lost the qos session
+     * @param session the corresponding qos session
+     */
+    public void sendEventQosSessionLost(final int qosCallbackId,
+            final QosSession session) {
+        runOnAgentConnection(qosCallbackId, "sendEventQosSessionLost: ",
+                ac -> ac.sendEventQosSessionLost(session));
+    }
+
+    /**
+     * Called when the NetworkAgent sends the qos session on error event
+     *
+     * @param qosCallbackId the callback id that should receive the exception
+     * @param exceptionType the type of exception that caused the callback to error
+     */
+    public void sendEventQosCallbackError(final int qosCallbackId,
+            @QosCallbackException.ExceptionType final int exceptionType) {
+        runOnAgentConnection(qosCallbackId, "sendEventQosCallbackError: ",
+                ac -> {
+                    ac.sendEventQosCallbackError(exceptionType);
+                    handleUnregisterCallback(ac.getBinder(), false);
+                });
+    }
+
+    /**
+     * Unregisters all callbacks associated to this network agent
+     *
+     * Note: Must be called on the connectivity service handler thread
+     *
+     * @param network the network that was released
+     */
+    public void handleNetworkReleased(@Nullable final Network network) {
+        final List<QosCallbackAgentConnection> connections =
+                CollectionUtils.filter(mConnections, ac -> ac.getNetwork().equals(network));
+
+        for (final QosCallbackAgentConnection agentConnection : connections) {
+            agentConnection.sendEventQosCallbackError(
+                    QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
+
+            // Call unregister workflow w\o sending anything to agent since it is disconnected.
+            handleUnregisterCallback(agentConnection.getBinder(), false);
+        }
+    }
+
+    private interface AgentConnectionAction {
+        void execute(@NonNull QosCallbackAgentConnection agentConnection);
+    }
+
+    @Nullable
+    private void runOnAgentConnection(final int qosCallbackId,
+            @NonNull final String logPrefix,
+            @NonNull final AgentConnectionAction action) {
+        mConnectivityServiceHandler.post(() -> {
+            final QosCallbackAgentConnection ac =
+                    CollectionUtils.find(mConnections,
+                            c -> c.getAgentCallbackId() == qosCallbackId);
+            if (ac == null) {
+                loge(logPrefix + ": " + qosCallbackId + " missing callback id");
+                return;
+            }
+
+            action.execute(ac);
+        });
+    }
+
+    private static void log(final String msg) {
+        Slog.d(TAG, msg);
+    }
+
+    private static void logw(final String msg) {
+        Slog.w(TAG, msg);
+    }
+
+    private static void loge(final String msg) {
+        Slog.e(TAG, msg);
+    }
+
+    private static void logwtf(final String msg) {
+        Slog.wtf(TAG, msg);
+    }
+}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 68708d36..d687221 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -24,6 +24,7 @@
 import android.view.DisplayAddress;
 
 import com.android.internal.BrightnessSynchronizer;
+import com.android.internal.R;
 import com.android.server.display.config.DisplayConfiguration;
 import com.android.server.display.config.DisplayQuirks;
 import com.android.server.display.config.HbmTiming;
@@ -64,6 +65,7 @@
     private static final String STABLE_ID_SUFFIX_FORMAT = "id_%d";
     private static final String NO_SUFFIX_FORMAT = "%d";
     private static final long STABLE_FLAG = 1L << 62;
+
     // Float.NaN (used as invalid for brightness) cannot be stored in config.xml
     // so -2 is used instead
     private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f;
@@ -75,6 +77,10 @@
     private float mBrightnessMinimum = Float.NaN;
     private float mBrightnessMaximum = Float.NaN;
     private float mBrightnessDefault = Float.NaN;
+    private float mBrightnessRampFastDecrease = Float.NaN;
+    private float mBrightnessRampFastIncrease = Float.NaN;
+    private float mBrightnessRampSlowDecrease = Float.NaN;
+    private float mBrightnessRampSlowIncrease = Float.NaN;
     private List<String> mQuirks;
     private boolean mIsHighBrightnessModeEnabled = false;
     private HighBrightnessModeData mHbmData;
@@ -177,6 +183,22 @@
         return mBrightnessDefault;
     }
 
+    public float getBrightnessRampFastDecrease() {
+        return mBrightnessRampFastDecrease;
+    }
+
+    public float getBrightnessRampFastIncrease() {
+        return mBrightnessRampFastIncrease;
+    }
+
+    public float getBrightnessRampSlowDecrease() {
+        return mBrightnessRampSlowDecrease;
+    }
+
+    public float getBrightnessRampSlowIncrease() {
+        return mBrightnessRampSlowIncrease;
+    }
+
     /**
      * @param quirkValue The quirk to test.
      * @return {@code true} if the specified quirk is present in this configuration,
@@ -210,6 +232,10 @@
                 + ", mQuirks=" + mQuirks
                 + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
                 + ", mHbmData=" + mHbmData
+                + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
+                + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+                + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
+                + ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
                 + "}";
         return str;
     }
@@ -265,6 +291,7 @@
                 loadBrightnessConstraintsFromConfigXml();
                 loadHighBrightnessModeData(config);
                 loadQuirks(config);
+                loadBrightnessRamps(config);
             } else {
                 Slog.w(TAG, "DisplayDeviceConfig file is null");
             }
@@ -278,6 +305,7 @@
         // If no ddc exists, use config.xml
         loadBrightnessDefaultFromConfigXml();
         loadBrightnessConstraintsFromConfigXml();
+        loadBrightnessRampsFromConfigXml();
     }
 
     private void initFromPmValues() {
@@ -397,6 +425,41 @@
         }
     }
 
+    private void loadBrightnessRamps(DisplayConfiguration config) {
+        // Priority 1: Value in the display device config (float)
+        // Priority 2: Value in the config.xml (int)
+        final BigDecimal fastDownDecimal = config.getScreenBrightnessRampFastDecrease();
+        final BigDecimal fastUpDecimal = config.getScreenBrightnessRampFastIncrease();
+        final BigDecimal slowDownDecimal = config.getScreenBrightnessRampSlowDecrease();
+        final BigDecimal slowUpDecimal = config.getScreenBrightnessRampSlowIncrease();
+
+        if (fastDownDecimal != null && fastUpDecimal != null && slowDownDecimal != null
+                && slowUpDecimal != null) {
+            mBrightnessRampFastDecrease = fastDownDecimal.floatValue();
+            mBrightnessRampFastIncrease = fastUpDecimal.floatValue();
+            mBrightnessRampSlowDecrease = slowDownDecimal.floatValue();
+            mBrightnessRampSlowIncrease = slowUpDecimal.floatValue();
+        } else {
+            if (fastDownDecimal != null || fastUpDecimal != null || slowDownDecimal != null
+                    || slowUpDecimal != null) {
+                Slog.w(TAG, "Per display brightness ramp values ignored because not all "
+                        + "values are present in display device config");
+            }
+            loadBrightnessRampsFromConfigXml();
+        }
+    }
+
+    private void loadBrightnessRampsFromConfigXml() {
+        mBrightnessRampFastIncrease = BrightnessSynchronizer.brightnessIntToFloat(
+                mContext.getResources().getInteger(R.integer.config_brightness_ramp_rate_fast));
+        mBrightnessRampSlowIncrease = BrightnessSynchronizer.brightnessIntToFloat(
+                mContext.getResources().getInteger(R.integer.config_brightness_ramp_rate_slow));
+        // config.xml uses the same values for both increasing and decreasing brightness
+        // transitions so we assign them to the same values here.
+        mBrightnessRampFastDecrease = mBrightnessRampFastIncrease;
+        mBrightnessRampSlowDecrease = mBrightnessRampSlowIncrease;
+    }
+
     /**
      * Container for high brightness mode configuration data.
      */
diff --git a/services/core/java/com/android/server/display/DisplayGroup.java b/services/core/java/com/android/server/display/DisplayGroup.java
index 1b5065a..2ba8758 100644
--- a/services/core/java/com/android/server/display/DisplayGroup.java
+++ b/services/core/java/com/android/server/display/DisplayGroup.java
@@ -21,8 +21,7 @@
 
 /**
  * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
- * operations; particularly display-state.
- *
+ * operations.
  * @hide
  */
 public class DisplayGroup {
@@ -36,44 +35,17 @@
         mGroupId = groupId;
     }
 
-    /** Returns the identifier for the Group. */
     int getGroupId() {
         return mGroupId;
     }
 
-    /**
-     * Adds the provided {@code display} to the Group
-     *
-     * @param display the {@link LogicalDisplay} to add to the Group
-     */
-    void addDisplayLocked(LogicalDisplay display) {
+    void addDisplay(LogicalDisplay display) {
         if (!mDisplays.contains(display)) {
             mDisplays.add(display);
         }
     }
 
-    /**
-     * Removes the provided {@code display} from the Group.
-     *
-     * @param display The {@link LogicalDisplay} to remove from the Group.
-     * @return {@code true} if the {@code display} was removed; otherwise {@code false}
-     */
-    boolean removeDisplayLocked(LogicalDisplay display) {
+    boolean removeDisplay(LogicalDisplay display) {
         return mDisplays.remove(display);
     }
-
-    /** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */
-    boolean isEmptyLocked() {
-        return mDisplays.isEmpty();
-    }
-
-    /** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */
-    int getSizeLocked() {
-        return mDisplays.size();
-    }
-
-    /** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */
-    int getIdLocked(int index) {
-        return mDisplays.get(index).getDisplayIdLocked();
-    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index bb4c9dd..55103ca 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -57,7 +57,6 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
 import android.hardware.display.DisplayViewport;
 import android.hardware.display.DisplayedContentSample;
@@ -191,7 +190,6 @@
     private static final int MSG_UPDATE_VIEWPORT = 5;
     private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
     private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
-    private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;
 
     private final Context mContext;
     private final DisplayManagerHandler mHandler;
@@ -239,54 +237,36 @@
     private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
             new CopyOnWriteArrayList<DisplayTransactionListener>();
 
-    /** List of all display group listeners. */
-    private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners =
-            new CopyOnWriteArrayList<>();
-
     /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */
     private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
             new SparseArray<>();
 
     /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */
     private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
-        // Synchronized to avoid race conditions when updating multiple display states.
         @Override
-        public synchronized void requestDisplayState(int displayId, int state, float brightness) {
-            boolean allInactive = true;
-            boolean allOff = true;
-            final boolean stateChanged;
+        public void requestDisplayState(int displayId, int state, float brightness) {
+            // TODO (b/168210494): Stop applying default display state to all displays.
+            if (displayId != Display.DEFAULT_DISPLAY) {
+                return;
+            }
+            final int[] displayIds;
             synchronized (mSyncRoot) {
-                final int index = mDisplayStates.indexOfKey(displayId);
-                final int newState = mDisplayStates.valueAt(index);
-                stateChanged = index == -1 || state != newState;
-                if (stateChanged) {
-                    final int size = mDisplayStates.size();
-                    for (int i = 0; i < size; i++) {
-                        final int displayState = i == index ? newState : state;
-                        if (displayState != Display.STATE_OFF) {
-                            allOff = false;
-                        }
-                        if (Display.isActiveState(displayState)) {
-                            allInactive = false;
-                        }
-                        if (!allOff && !allInactive) {
-                            break;
-                        }
-                    }
-                }
+                displayIds = mLogicalDisplayMapper.getDisplayIdsLocked();
             }
 
             // The order of operations is important for legacy reasons.
             if (state == Display.STATE_OFF) {
-                requestDisplayStateInternal(displayId, state, brightness);
+                for (int id : displayIds) {
+                    requestDisplayStateInternal(id, state, brightness);
+                }
             }
 
-            if (stateChanged) {
-                mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff);
-            }
+            mDisplayPowerCallbacks.onDisplayStateChange(state);
 
             if (state != Display.STATE_OFF) {
-                requestDisplayStateInternal(displayId, state, brightness);
+                for (int id : displayIds) {
+                    requestDisplayStateInternal(id, state, brightness);
+                }
             }
         }
     };
@@ -1172,7 +1152,7 @@
 
     private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) {
         final int displayId = display.getDisplayIdLocked();
-        mDisplayPowerControllers.removeReturnOld(displayId).stop();
+        mDisplayPowerControllers.delete(displayId);
         mDisplayStates.delete(displayId);
         mDisplayBrightnesses.delete(displayId);
         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
@@ -1689,11 +1669,6 @@
         mHandler.sendMessage(msg);
     }
 
-    private void sendDisplayGroupEvent(int groupId, int event) {
-        Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event);
-        mHandler.sendMessage(msg);
-    }
-
     private void sendDisplayEventFrameRateOverrideLocked(int displayId) {
         Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
                 displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
@@ -1738,35 +1713,6 @@
         mTempCallbacks.clear();
     }
 
-    // Runs on Handler thread.
-    // Delivers display group event notifications to callbacks.
-    private void deliverDisplayGroupEvent(int groupId, int event) {
-        if (DEBUG) {
-            Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event="
-                    + event);
-        }
-
-        switch (event) {
-            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED:
-                for (DisplayGroupListener listener : mDisplayGroupListeners) {
-                    listener.onDisplayGroupAdded(groupId);
-                }
-                break;
-
-            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED:
-                for (DisplayGroupListener listener : mDisplayGroupListeners) {
-                    listener.onDisplayGroupChanged(groupId);
-                }
-                break;
-
-            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED:
-                for (DisplayGroupListener listener : mDisplayGroupListeners) {
-                    listener.onDisplayGroupRemoved(groupId);
-                }
-                break;
-        }
-    }
-
     private IMediaProjectionManager getProjectionService() {
         if (mProjectionService == null) {
             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
@@ -1989,11 +1935,6 @@
                     }
                     deliverDisplayEvent(msg.arg1, uids, msg.arg2);
                     break;
-
-                case MSG_DELIVER_DISPLAY_GROUP_EVENT:
-                    deliverDisplayGroupEvent(msg.arg1, msg.arg2);
-                    break;
-
             }
         }
     }
@@ -2025,11 +1966,6 @@
         }
 
         @Override
-        public void onDisplayGroupEventLocked(int groupId, int event) {
-            sendDisplayGroupEvent(groupId, event);
-        }
-
-        @Override
         public void onTraversalRequested() {
             synchronized (mSyncRoot) {
                 scheduleTraversalLocked(false);
@@ -2764,25 +2700,11 @@
         }
 
         @Override
-        public boolean requestPowerState(int groupId, DisplayPowerRequest request,
+        public boolean requestPowerState(DisplayPowerRequest request,
                 boolean waitForNegativeProximity) {
             synchronized (mSyncRoot) {
-                final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked(
-                        groupId);
-                if (displayGroup == null) {
-                    return true;
-                }
-
-                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);
-                }
-
-                return ready;
+                return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                        .requestPowerState(request, waitForNegativeProximity);
             }
         }
 
@@ -2795,13 +2717,10 @@
         }
 
         @Override
-        public void registerDisplayGroupListener(DisplayGroupListener listener) {
-            mDisplayGroupListeners.add(listener);
-        }
-
-        @Override
-        public void unregisterDisplayGroupListener(DisplayGroupListener listener) {
-            mDisplayGroupListeners.remove(listener);
+        public int getDisplayGroupId(int displayId) {
+            synchronized (mSyncRoot) {
+                return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId);
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 5c795cd..d9ee9a3 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -331,8 +331,10 @@
     private BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
 
     // Brightness animation ramp rates in brightness units per second
-    private final float mBrightnessRampRateSlow;
-    private final float mBrightnessRampRateFast;
+    private float mBrightnessRampRateFastDecrease;
+    private float mBrightnessRampRateFastIncrease;
+    private float mBrightnessRampRateSlowDecrease;
+    private float mBrightnessRampRateSlowIncrease;
 
 
     // Whether or not to skip the initial brightness ramps into STATE_ON.
@@ -459,10 +461,21 @@
         mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
 
-        mBrightnessRampRateFast = BrightnessSynchronizer.brightnessIntToFloat(resources.getInteger(
-                com.android.internal.R.integer.config_brightness_ramp_rate_fast));
-        mBrightnessRampRateSlow = BrightnessSynchronizer.brightnessIntToFloat(resources.getInteger(
-                com.android.internal.R.integer.config_brightness_ramp_rate_slow));
+
+        DisplayDeviceConfig displayDeviceConfig = logicalDisplay
+                .getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
+        // TODO: (b/178183143) Ensure that the ddc is not null
+        if (displayDeviceConfig != null) {
+            mBrightnessRampRateFastDecrease = displayDeviceConfig.getBrightnessRampFastDecrease();
+            mBrightnessRampRateFastIncrease = displayDeviceConfig.getBrightnessRampFastIncrease();
+            mBrightnessRampRateSlowDecrease = displayDeviceConfig.getBrightnessRampSlowDecrease();
+            mBrightnessRampRateSlowIncrease = displayDeviceConfig.getBrightnessRampSlowIncrease();
+        } else {
+            mBrightnessRampRateFastDecrease = 1.0f;
+            mBrightnessRampRateFastIncrease = 1.0f;
+            mBrightnessRampRateSlowDecrease = 1.0f;
+            mBrightnessRampRateSlowIncrease = 1.0f;
+        }
         mSkipScreenOnBrightnessRamp = resources.getBoolean(
                 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
 
@@ -683,17 +696,6 @@
         // TODO: b/175821789 - Support high brightness on multiple (folding) displays
     }
 
-    /**
-     * Unregisters all listeners and interrupts all running threads; halting future work.
-     *
-     * This method should be called when the DisplayPowerController is no longer in use; i.e. when
-     * the {@link #mDisplayId display} has been removed.
-     */
-    public void stop() {
-        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
-        mPowerState.stop();
-    }
-
     private void sendUpdatePowerState() {
         synchronized (mLock) {
             sendUpdatePowerStateLocked();
@@ -783,7 +785,6 @@
         boolean mustInitialize = false;
         int brightnessAdjustmentFlags = 0;
         mBrightnessReasonTemp.set(null);
-
         synchronized (mLock) {
             mPendingUpdatePowerStateLocked = false;
             if (mPendingRequestLocked == null) {
@@ -1122,13 +1123,25 @@
             // user even when the display is all black.
             float animateValue = brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT
                     ? PowerManager.BRIGHTNESS_MIN : brightnessState;
-            if (isValidBrightnessValue(animateValue)) {
+            final float currentBrightness = mPowerState.getScreenBrightness();
+            if (isValidBrightnessValue(animateValue)
+                    && !BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)) {
                 if (initialRampSkip || hasBrightnessBuckets
                         || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                     animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
                 } else {
-                    animateScreenBrightness(animateValue,
-                            slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
+                    boolean isIncreasing = animateValue > currentBrightness;
+                    final float rampSpeed;
+                    if (isIncreasing && slowChange) {
+                        rampSpeed = mBrightnessRampRateSlowIncrease;
+                    } else if (isIncreasing && !slowChange) {
+                        rampSpeed = mBrightnessRampRateFastIncrease;
+                    } else if (!isIncreasing && slowChange) {
+                        rampSpeed = mBrightnessRampRateSlowDecrease;
+                    } else {
+                        rampSpeed = mBrightnessRampRateFastDecrease;
+                    }
+                    animateScreenBrightness(animateValue, rampSpeed);
                 }
             }
 
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index 51ba065..54f30a9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -72,8 +72,6 @@
 
     private Runnable mCleanListener;
 
-    private volatile boolean mStopped;
-
     public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId) {
         mHandler = new Handler(true /*async*/);
         mChoreographer = Choreographer.getInstance();
@@ -265,18 +263,6 @@
         }
     }
 
-    /**
-     * Interrupts all running threads; halting future work.
-     *
-     * This method should be called when the DisplayPowerState is no longer in use; i.e. when
-     * the {@link #mDisplayId display} has been removed.
-     */
-    public void stop() {
-        mHandler.removeCallbacksAndMessages(null);
-        mStopped = true;
-        mPhotonicModulator.interrupt();
-    }
-
     public void dump(PrintWriter pw) {
         pw.println();
         pw.println("Display Power State:");
@@ -441,11 +427,7 @@
                     if (!stateChanged && !backlightChanged) {
                         try {
                             mLock.wait();
-                        } catch (InterruptedException ex) {
-                            if (mStopped) {
-                                return;
-                            }
-                        }
+                        } catch (InterruptedException ex) { }
                         continue;
                     }
                     mActualState = state;
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index ecb837d..bb2fbed 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import android.content.Context;
+import android.os.Process;
 import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.IndentingPrintWriter;
@@ -54,10 +55,6 @@
     public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4;
     public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 5;
 
-    public static final int DISPLAY_GROUP_EVENT_ADDED = 1;
-    public static final int DISPLAY_GROUP_EVENT_CHANGED = 2;
-    public static final int DISPLAY_GROUP_EVENT_REMOVED = 3;
-
     /**
      * Temporary display info, used for comparing display configurations.
      */
@@ -102,7 +99,7 @@
     private int mNextNonDefaultGroupId = DisplayGroup.DEFAULT + 1;
 
     /** A mapping from logical display id to display group. */
-    private final SparseArray<DisplayGroup> mDisplayIdToGroupMap = new SparseArray<>();
+    private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
 
     private final DisplayDeviceRepository mDisplayDeviceRepo;
     private final Listener mListener;
@@ -157,6 +154,10 @@
         return null;
     }
 
+    public int[] getDisplayIdsLocked() {
+        return getDisplayIdsLocked(Process.SYSTEM_UID);
+    }
+
     public int[] getDisplayIdsLocked(int callingUid) {
         final int count = mLogicalDisplays.size();
         int[] displayIds = new int[count];
@@ -181,16 +182,13 @@
         }
     }
 
-    public DisplayGroup getDisplayGroupLocked(int groupId) {
-        final int size = mDisplayIdToGroupMap.size();
-        for (int i = 0; i < size; i++) {
-            final DisplayGroup displayGroup = mDisplayIdToGroupMap.valueAt(i);
-            if (displayGroup.getGroupId() == groupId) {
-                return displayGroup;
-            }
+    public int getDisplayGroupIdLocked(int displayId) {
+        final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
+        if (displayGroup != null) {
+            return displayGroup.getGroupId();
         }
 
-        return null;
+        return -1;
     }
 
     public void dumpLocked(PrintWriter pw) {
@@ -327,31 +325,17 @@
         mLogicalDisplays.put(displayId, display);
 
         final DisplayGroup displayGroup;
-        final boolean addNewDisplayGroup =
-                isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0;
-        if (addNewDisplayGroup) {
+        if (isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
             final int groupId = assignDisplayGroupIdLocked(isDefault);
             displayGroup = new DisplayGroup(groupId);
         } else {
-            displayGroup = mDisplayIdToGroupMap.get(Display.DEFAULT_DISPLAY);
+            displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
         }
-        displayGroup.addDisplayLocked(display);
-        mDisplayIdToGroupMap.append(displayId, displayGroup);
-
-        if (addNewDisplayGroup) {
-            // Group added events happen before Logical Display added events.
-            mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
-                    LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
-        }
+        displayGroup.addDisplay(display);
+        mDisplayGroups.append(displayId, displayGroup);
 
         mListener.onLogicalDisplayEventLocked(display,
                 LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED);
-
-        if (!addNewDisplayGroup) {
-            // Group changed events happen after Logical Display added events.
-            mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
-                    LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
-        }
     }
 
     /**
@@ -368,45 +352,31 @@
             DisplayEventReceiver.FrameRateOverride[] frameRatesOverrides =
                     display.getFrameRateOverrides();
             display.updateLocked(mDisplayDeviceRepo);
-            final DisplayGroup changedDisplayGroup;
             if (!display.isValidLocked()) {
                 mLogicalDisplays.removeAt(i);
-                final DisplayGroup displayGroup = mDisplayIdToGroupMap.removeReturnOld(displayId);
-                displayGroup.removeDisplayLocked(display);
+                mDisplayGroups.removeReturnOld(displayId).removeDisplay(display);
 
                 mListener.onLogicalDisplayEventLocked(display,
                         LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED);
-
-                changedDisplayGroup = displayGroup;
             } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
                 final int flags = display.getDisplayInfoLocked().flags;
-                final DisplayGroup defaultDisplayGroup = mDisplayIdToGroupMap.get(
+                final DisplayGroup defaultDisplayGroup = mDisplayGroups.get(
                         Display.DEFAULT_DISPLAY);
                 if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
                     // The display should have its own DisplayGroup.
-                    if (defaultDisplayGroup.removeDisplayLocked(display)) {
+                    if (defaultDisplayGroup.removeDisplay(display)) {
                         final int groupId = assignDisplayGroupIdLocked(false);
                         final DisplayGroup displayGroup = new DisplayGroup(groupId);
-                        displayGroup.addDisplayLocked(display);
-                        mDisplayIdToGroupMap.append(display.getDisplayIdLocked(), displayGroup);
-                        mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
-                                LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
-                        changedDisplayGroup = defaultDisplayGroup;
-                    } else {
-                        changedDisplayGroup = null;
+                        displayGroup.addDisplay(display);
+                        mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
                     }
                 } else {
                     // The display should be a part of the default DisplayGroup.
-                    final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
+                    final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
                     if (displayGroup != defaultDisplayGroup) {
-                        displayGroup.removeDisplayLocked(display);
-                        defaultDisplayGroup.addDisplayLocked(display);
-                        mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
-                                LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
-                        mDisplayIdToGroupMap.put(displayId, defaultDisplayGroup);
-                        changedDisplayGroup = displayGroup;
-                    } else {
-                        changedDisplayGroup = null;
+                        displayGroup.removeDisplay(display);
+                        defaultDisplayGroup.addDisplay(display);
+                        mDisplayGroups.put(displayId, defaultDisplayGroup);
                     }
                 }
 
@@ -418,7 +388,6 @@
             } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
                 mListener.onLogicalDisplayEventLocked(display,
                         LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
-                changedDisplayGroup = null;
             } else {
                 // While applications shouldn't know nor care about the non-overridden info, we
                 // still need to let WindowManager know so it can update its own internal state for
@@ -428,15 +397,6 @@
                     mListener.onLogicalDisplayEventLocked(display,
                             LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED);
                 }
-                changedDisplayGroup = null;
-            }
-
-            // CHANGED and REMOVED DisplayGroup events should always fire after Display events.
-            if (changedDisplayGroup != null) {
-                final int event = changedDisplayGroup.isEmptyLocked()
-                        ? LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED
-                        : LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED;
-                mListener.onDisplayGroupEventLocked(changedDisplayGroup.getGroupId(), event);
             }
         }
     }
@@ -472,7 +432,6 @@
 
     public interface Listener {
         void onLogicalDisplayEventLocked(LogicalDisplay display, int event);
-        void onDisplayGroupEventLocked(int groupId, int event);
         void onTraversalRequested();
     }
 }
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index a0d9e8e..425e3ab 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -31,6 +31,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.security.FileIntegrityService;
+import com.android.server.security.VerityUtils;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -39,6 +41,7 @@
 import java.nio.ByteBuffer;
 import java.nio.NioUtils;
 import java.nio.channels.FileChannel;
+import java.util.Arrays;
 import java.util.Map;
 
 /** A service for managing system fonts. */
@@ -78,7 +81,17 @@
 
     private static class OtfFontFileParser implements UpdatableFontDir.FontFileParser {
         @Override
-        public long getVersion(File file) throws IOException {
+        public String getPostScriptName(File file) throws IOException {
+            ByteBuffer buffer = mmap(file);
+            try {
+                return FontFileUtil.getPostScriptName(buffer, 0);
+            } finally {
+                NioUtils.freeDirectBuffer(buffer);
+            }
+        }
+
+        @Override
+        public long getRevision(File file) throws IOException {
             ByteBuffer buffer = mmap(file);
             try {
                 return FontFileUtil.getRevision(buffer, 0);
@@ -95,18 +108,48 @@
         }
     }
 
+    private static class FsverityUtilImpl implements UpdatableFontDir.FsverityUtil {
+        @Override
+        public boolean hasFsverity(String filePath) {
+            return VerityUtils.hasFsverity(filePath);
+        }
+
+        @Override
+        public void setUpFsverity(String filePath, byte[] pkcs7Signature) throws IOException {
+            VerityUtils.setUpFsverity(filePath, pkcs7Signature);
+        }
+
+        @Override
+        public boolean rename(File src, File dest) {
+            // rename system call preserves fs-verity bit.
+            return src.renameTo(dest);
+        }
+    }
+
     @Nullable
     private final UpdatableFontDir mUpdatableFontDir;
 
     @GuardedBy("FontManagerService.this")
-    @Nullable SystemFontSettings mCurrentFontSettings = null;
+    @Nullable
+    private SystemFontSettings mCurrentFontSettings = null;
 
     private FontManagerService() {
-        mUpdatableFontDir = ENABLE_FONT_UPDATES
-                ? new UpdatableFontDir(new File(FONT_FILES_DIR), new OtfFontFileParser()) : null;
+        mUpdatableFontDir = createUpdatableFontDir();
     }
 
-    @NonNull private SystemFontSettings getCurrentFontSettings() {
+    @Nullable
+    private static UpdatableFontDir createUpdatableFontDir() {
+        if (!ENABLE_FONT_UPDATES) return null;
+        // If apk verity is supported, fs-verity should be available.
+        if (!FileIntegrityService.isApkVeritySupported()) return null;
+        return new UpdatableFontDir(new File(FONT_FILES_DIR),
+                Arrays.asList(new File(SystemFonts.SYSTEM_FONT_DIR),
+                        new File(SystemFonts.OEM_FONT_DIR)),
+                new OtfFontFileParser(), new FsverityUtilImpl());
+    }
+
+    @NonNull
+    private SystemFontSettings getCurrentFontSettings() {
         synchronized (FontManagerService.this) {
             if (mCurrentFontSettings == null) {
                 mCurrentFontSettings = SystemFontSettings.create(mUpdatableFontDir);
@@ -115,13 +158,14 @@
         }
     }
 
-    private boolean installFontFile(String name, FileDescriptor fd) {
+    // TODO(b/173619554): Expose as API.
+    private boolean installFontFile(FileDescriptor fd, byte[] pkcs7Signature) {
         if (mUpdatableFontDir == null) return false;
         synchronized (FontManagerService.this) {
             try {
-                mUpdatableFontDir.installFontFile(name, fd);
+                mUpdatableFontDir.installFontFile(fd, pkcs7Signature);
             } catch (IOException e) {
-                Slog.w(TAG, "Failed to install font file: " + name, e);
+                Slog.w(TAG, "Failed to install font file");
                 return false;
             }
             // Create updated font map in the next getSerializedSystemFontMap() call.
@@ -194,5 +238,5 @@
             }
             return null;
         }
-    };
+    }
 }
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 7306471..8da579f 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -16,6 +16,7 @@
 
 package com.android.server.graphics.fonts;
 
+import android.annotation.Nullable;
 import android.os.FileUtils;
 import android.util.Base64;
 import android.util.Slog;
@@ -28,71 +29,158 @@
 import java.io.IOException;
 import java.security.SecureRandom;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 final class UpdatableFontDir {
 
     private static final String TAG = "UpdatableFontDir";
     private static final String RANDOM_DIR_PREFIX = "~~";
+    // TODO: Support .otf
+    private static final String ALLOWED_EXTENSION = ".ttf";
 
     /** Interface to mock font file access in tests. */
     interface FontFileParser {
-        long getVersion(File file) throws IOException;
+        String getPostScriptName(File file) throws IOException;
+
+        long getRevision(File file) throws IOException;
     }
 
-    /** Data class to hold font file path and version. */
-    static final class FontFileInfo {
-        final File mFile;
-        final long mVersion;
+    /** Interface to mock fs-verity in tests. */
+    interface FsverityUtil {
+        boolean hasFsverity(String path);
 
-        FontFileInfo(File file, long version) {
+        void setUpFsverity(String path, byte[] pkcs7Signature) throws IOException;
+
+        boolean rename(File src, File dest);
+    }
+
+    /** Data class to hold font file path and revision. */
+    private static final class FontFileInfo {
+        private final File mFile;
+        private final long mRevision;
+
+        FontFileInfo(File file, long revision) {
             mFile = file;
-            mVersion = version;
+            mRevision = revision;
+        }
+
+        public File getFile() {
+            return mFile;
+        }
+
+        /** Returns the unique randomized font dir containing this font file. */
+        public File getRandomizedFontDir() {
+            return mFile.getParentFile();
+        }
+
+        public long getRevision() {
+            return mRevision;
         }
     }
 
     /**
-     * Root directory for storing updated font files. Each font file is stored in a unique random
-     * dir. The font file path would be {@code mFilesDir/~~{randomStr}/{fontFileName}}.
+     * Root directory for storing updated font files. Each font file is stored in a unique
+     * randomized dir. The font file path would be {@code mFilesDir/~~{randomStr}/{fontFileName}}.
      */
     private final File mFilesDir;
+    private final List<File> mPreinstalledFontDirs;
     private final FontFileParser mParser;
+    private final FsverityUtil mFsverityUtil;
+    /**
+     * A mutable map containing mapping from font file name (e.g. "NotoColorEmoji.ttf") to {@link
+     * FontFileInfo}. All files in this map are validated, and have higher revision numbers than
+     * corresponding font files in {@link #mPreinstalledFontDirs}.
+     */
     @GuardedBy("UpdatableFontDir.this")
     private final Map<String, FontFileInfo> mFontFileInfoMap = new HashMap<>();
 
-    UpdatableFontDir(File filesDir, FontFileParser parser) {
+    UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser,
+            FsverityUtil fsverityUtil) {
         mFilesDir = filesDir;
+        mPreinstalledFontDirs = preinstalledFontDirs;
         mParser = parser;
+        mFsverityUtil = fsverityUtil;
         loadFontFileMap();
     }
 
     private void loadFontFileMap() {
+        // TODO: SIGBUS crash protection
         synchronized (UpdatableFontDir.this) {
+            boolean success = false;
             mFontFileInfoMap.clear();
-            File[] dirs = mFilesDir.listFiles();
-            if (dirs == null) return;
-            for (File dir : dirs) {
-                if (!dir.getName().startsWith(RANDOM_DIR_PREFIX)) continue;
-                File[] files = dir.listFiles();
-                if (files == null || files.length != 1) continue;
-                addFileToMapLocked(files[0], true);
+            try {
+                File[] dirs = mFilesDir.listFiles();
+                if (dirs == null) return;
+                for (File dir : dirs) {
+                    if (!dir.getName().startsWith(RANDOM_DIR_PREFIX)) return;
+                    File[] files = dir.listFiles();
+                    if (files == null || files.length != 1) return;
+                    FontFileInfo fontFileInfo = validateFontFile(files[0]);
+                    if (fontFileInfo == null) {
+                        Slog.w(TAG, "Broken file is found. Clearing files.");
+                        return;
+                    }
+                    addFileToMapLocked(fontFileInfo, true /* deleteOldFile */);
+                }
+                success = true;
+            } finally {
+                // Delete all files just in case if we find a problematic file.
+                if (!success) {
+                    mFontFileInfoMap.clear();
+                    FileUtils.deleteContents(mFilesDir);
+                }
             }
         }
     }
 
-    void installFontFile(String name, FileDescriptor fd) throws IOException {
-        // TODO: Validate name.
+    /**
+     * Installs a new font file, or updates an existing font file.
+     *
+     * <p>The new font will be immediately available for new Zygote-forked processes through
+     * {@link #getFontFileMap()}. Old font files will be kept until next system server reboot,
+     * because existing Zygote-forked processes have paths to old font files.
+     *
+     * @param fd             A file descriptor to the font file.
+     * @param pkcs7Signature A PKCS#7 detached signature to enable fs-verity for the font file.
+     */
+    void installFontFile(FileDescriptor fd, byte[] pkcs7Signature) throws IOException {
         synchronized (UpdatableFontDir.this) {
-            // TODO: proper error handling
             File newDir = getRandomDir(mFilesDir);
             if (!newDir.mkdir()) {
+                // TODO: Define and return an error code for API
                 throw new IOException("Failed to create a new dir");
             }
-            File newFontFile = new File(newDir, name);
-            try (FileOutputStream out = new FileOutputStream(newFontFile)) {
-                FileUtils.copy(fd, out.getFD());
+            boolean success = false;
+            try {
+                File tempNewFontFile = new File(newDir, "font.ttf");
+                try (FileOutputStream out = new FileOutputStream(tempNewFontFile)) {
+                    FileUtils.copy(fd, out.getFD());
+                }
+                // Do not parse font file before setting up fs-verity.
+                // setUpFsverity throws IOException if failed.
+                mFsverityUtil.setUpFsverity(tempNewFontFile.getAbsolutePath(), pkcs7Signature);
+                String postScriptName = mParser.getPostScriptName(tempNewFontFile);
+                File newFontFile = new File(newDir, postScriptName + ALLOWED_EXTENSION);
+                if (!mFsverityUtil.rename(tempNewFontFile, newFontFile)) {
+                    // TODO: Define and return an error code for API
+                    throw new IOException("Failed to rename");
+                }
+                FontFileInfo fontFileInfo = validateFontFile(newFontFile);
+                if (fontFileInfo == null) {
+                    // TODO: Define and return an error code for API
+                    throw new IllegalArgumentException("Invalid file");
+                }
+                if (!addFileToMapLocked(fontFileInfo, false)) {
+                    // TODO: Define and return an error code for API
+                    throw new IllegalArgumentException("Version downgrade");
+                }
+                success = true;
+            } finally {
+                if (!success) {
+                    FileUtils.deleteContentsAndDir(newDir);
+                }
             }
-            addFileToMapLocked(newFontFile, false);
         }
     }
 
@@ -114,27 +202,110 @@
         return dir;
     }
 
-    private void addFileToMapLocked(File file, boolean deleteOldFile) {
-        final long version;
+    /**
+     * Add the given {@link FontFileInfo} to {@link #mFontFileInfoMap} if its font revision is
+     * higher than the currently used font file (either in {@link #mFontFileInfoMap} or {@link
+     * #mPreinstalledFontDirs}).
+     */
+    private boolean addFileToMapLocked(FontFileInfo fontFileInfo, boolean deleteOldFile) {
+        String name = fontFileInfo.getFile().getName();
+        FontFileInfo existingInfo = mFontFileInfoMap.get(name);
+        final boolean shouldAddToMap;
+        if (existingInfo == null) {
+            // We got a new updatable font. We need to check if it's newer than preinstalled fonts.
+            // Note that getPreinstalledFontRevision() returns -1 if there is no preinstalled font
+            // with 'name'.
+            shouldAddToMap = getPreinstalledFontRevision(name) < fontFileInfo.getRevision();
+        } else {
+            shouldAddToMap = existingInfo.getRevision() < fontFileInfo.getRevision();
+        }
+        if (shouldAddToMap) {
+            if (deleteOldFile && existingInfo != null) {
+                FileUtils.deleteContentsAndDir(existingInfo.getRandomizedFontDir());
+            }
+            mFontFileInfoMap.put(name, fontFileInfo);
+            return true;
+        } else {
+            if (deleteOldFile) {
+                FileUtils.deleteContentsAndDir(fontFileInfo.getRandomizedFontDir());
+            }
+            return false;
+        }
+    }
+
+    private long getPreinstalledFontRevision(String name) {
+        long maxRevision = -1;
+        for (File dir : mPreinstalledFontDirs) {
+            File preinstalledFontFile = new File(dir, name);
+            if (!preinstalledFontFile.exists()) continue;
+            long revision = getFontRevision(preinstalledFontFile);
+            if (revision == -1) {
+                Slog.w(TAG, "Invalid preinstalled font file");
+                continue;
+            }
+            if (revision > maxRevision) {
+                maxRevision = revision;
+            }
+        }
+        return maxRevision;
+    }
+
+    /**
+     * Checks the fs-verity protection status of the given font file, validates the file name, and
+     * returns a {@link FontFileInfo} on success. This method does not check if the font revision
+     * is higher than the currently used font.
+     */
+    @Nullable
+    private FontFileInfo validateFontFile(File file) {
+        if (!mFsverityUtil.hasFsverity(file.getAbsolutePath())) {
+            Slog.w(TAG, "Font validation failed. Fs-verity is not enabled: " + file);
+            return null;
+        }
+        if (!validateFontFileName(file)) {
+            Slog.w(TAG, "Font validation failed. Could not validate font file name: " + file);
+            return null;
+        }
+        long revision = getFontRevision(file);
+        if (revision == -1) {
+            Slog.w(TAG, "Font validation failed. Could not read font revision: " + file);
+            return null;
+        }
+        return new FontFileInfo(file, revision);
+    }
+
+    /**
+     * Returns true if the font file's file name matches with the PostScript name metadata in the
+     * font file.
+     *
+     * <p>We check the font file names because apps use file name to look up fonts.
+     * <p>Because PostScript name does not include extension, the extension is appended for
+     * comparison. For example, if the file name is "NotoColorEmoji.ttf", the PostScript name should
+     * be "NotoColorEmoji".
+     */
+    private boolean validateFontFileName(File file) {
+        String fileName = file.getName();
+        String postScriptName = getPostScriptName(file);
+        return (postScriptName + ALLOWED_EXTENSION).equals(fileName);
+    }
+
+    /** Returns the PostScript name of the given font file, or null. */
+    @Nullable
+    private String getPostScriptName(File file) {
         try {
-            version = mParser.getVersion(file);
+            return mParser.getPostScriptName(file);
         } catch (IOException e) {
             Slog.e(TAG, "Failed to read font file", e);
-            return;
+            return null;
         }
-        if (version == -1) {
-            Slog.e(TAG, "Invalid font file");
-            return;
-        }
-        FontFileInfo info = mFontFileInfoMap.get(file.getName());
-        if (info == null) {
-            // TODO: check version of font in /system/fonts and /product/fonts
-            mFontFileInfoMap.put(file.getName(), new FontFileInfo(file, version));
-        } else if (info.mVersion < version) {
-            if (deleteOldFile) {
-                FileUtils.deleteContentsAndDir(info.mFile.getParentFile());
-            }
-            mFontFileInfoMap.put(file.getName(), new FontFileInfo(file, version));
+    }
+
+    /** Returns the non-negative font revision of the given font file, or -1. */
+    private long getFontRevision(File file) {
+        try {
+            return mParser.getRevision(file);
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to read font file", e);
+            return -1;
         }
     }
 
@@ -142,7 +313,7 @@
         Map<String, File> map = new HashMap<>();
         synchronized (UpdatableFontDir.this) {
             for (Map.Entry<String, FontFileInfo> entry : mFontFileInfoMap.entrySet()) {
-                map.put(entry.getKey(), entry.getValue().mFile);
+                map.put(entry.getKey(), entry.getValue().getFile());
             }
         }
         return map;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 141fa6a..f92f3dc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -39,11 +39,6 @@
     public abstract void resetUserState(int userId);
 
     /**
-     * @return true if the given uid is restricted from doing networking on metered networks.
-     */
-    public abstract boolean isUidRestrictedOnMeteredNetworks(int uid);
-
-    /**
      * Figure out if networking is blocked for a given set of conditions.
      *
      * This is used by ConnectivityService via passing stale copies of conditions, so it must not
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 69b9be1..29eaf4f 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -5383,7 +5383,7 @@
     public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
         final long startTime = mStatLogger.getTime();
 
-        enforceAnyPermissionOf(OBSERVE_NETWORK_POLICY, PERMISSION_MAINLINE_NETWORK_STACK);
+        mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
         final int uidRules;
         final boolean isBackgroundRestricted;
         synchronized (mUidRulesFirstLock) {
@@ -5398,6 +5398,23 @@
         return ret;
     }
 
+    @Override
+    public boolean isUidRestrictedOnMeteredNetworks(int uid) {
+        mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
+        final int uidRules;
+        final boolean isBackgroundRestricted;
+        synchronized (mUidRulesFirstLock) {
+            uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
+            isBackgroundRestricted = mRestrictBackground;
+        }
+        //TODO(b/177490332): The logic here might not be correct because it doesn't consider
+        // RULE_REJECT_METERED condition. And it could be replaced by
+        // isUidNetworkingBlockedInternal().
+        return isBackgroundRestricted
+                && !hasRule(uidRules, RULE_ALLOW_METERED)
+                && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
+    }
+
     private static boolean isSystem(int uid) {
         return uid < Process.FIRST_APPLICATION_UID;
     }
@@ -5466,22 +5483,6 @@
             }
         }
 
-        /**
-         * @return true if the given uid is restricted from doing networking on metered networks.
-         */
-        @Override
-        public boolean isUidRestrictedOnMeteredNetworks(int uid) {
-            final int uidRules;
-            final boolean isBackgroundRestricted;
-            synchronized (mUidRulesFirstLock) {
-                uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
-                isBackgroundRestricted = mRestrictBackground;
-            }
-            return isBackgroundRestricted
-                    && !hasRule(uidRules, RULE_ALLOW_METERED)
-                    && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
-        }
-
         @Override
         public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
             synchronized (mUidRulesFirstLock) {
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index ef0f0ee..4ff75fa 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -336,6 +336,13 @@
 
         @Override
         public void binderDied() {
+            try {
+                // Allow a small amount of time for any error or finished callbacks to be made.
+                // This ensures that the listener does not receive an erroneous runtime error
+                // callback.
+                Thread.sleep(1000);
+            } catch (InterruptedException ignored) {
+            }
             synchronized (mLock) {
                 if (!mDone) {
                     // If we have not gotten a "done" callback this must be a crash.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e7a04ef..2eeb56e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8802,7 +8802,17 @@
     @Override
     public String getPermissionControllerPackageName() {
         synchronized (mLock) {
-            return mRequiredPermissionControllerPackage;
+            if (mRequiredPermissionControllerPackage != null) {
+                final PackageSetting ps = getPackageSetting(mRequiredPermissionControllerPackage);
+                if (ps != null) {
+                    final int callingUid = Binder.getCallingUid();
+                    final int callingUserId = UserHandle.getUserId(callingUid);
+                    if (!shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
+                        return mRequiredPermissionControllerPackage;
+                    }
+                }
+            }
+            throw new IllegalStateException("PermissionController is not found");
         }
     }
 
@@ -21423,7 +21433,7 @@
                 mPermissionManager.onPackageInstalled(pkg,
                         PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, userId);
                 if (applyUserRestrictions) {
-                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+                    mSettings.writePermissionStateForUserLPr(userId, false);
                 }
             }
 
@@ -27429,7 +27439,7 @@
         public void writePermissionSettings(int[] userIds, boolean async) {
             synchronized (mLock) {
                 for (int userId : userIds) {
-                    mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
+                    mSettings.writePermissionStateForUserLPr(userId, !async);
                 }
             }
         }
@@ -28069,13 +28079,12 @@
 
     /**
      * Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's
-     * writeLegacyPermissionsTEMP() and writeLegacyPermissionStateTEMP() beforehand.
+     * writeLegacyPermissionsTEMP() beforehand.
      *
      * TODO(zhanghai): This should be removed once we finish migration of permission storage.
      */
     private void writeSettingsLPrTEMP() {
         mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
-        mPermissionManager.writeLegacyPermissionStateTEMP();
         mSettings.writeLPr();
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 9eae117..446342a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2732,7 +2732,7 @@
     private int removeUserOrSetEphemeral(IUserManager um, @UserIdInt int userId)
             throws RemoteException {
         Slog.i(TAG, "Removing " + userId + " or set as ephemeral if in use.");
-        int result = um.removeUserOrSetEphemeral(userId);
+        int result = um.removeUserOrSetEphemeral(userId, /* evenWhenDisallowed= */ false);
         switch (result) {
             case UserManager.REMOVE_RESULT_REMOVED:
                 getOutPrintWriter().printf("Success: user %d removed\n", userId);
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 83f6c52..ade087b 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -356,7 +356,7 @@
             proto.write(PackageProto.UserPermissionsProto.ID, user.id);
 
             runtimePermissionStates = dataProvider.getLegacyPermissionState(appId)
-                    .getRuntimePermissionStates(user.id);
+                    .getPermissionStates(user.id);
             for (LegacyPermissionState.PermissionState permission : runtimePermissionStates) {
                 if (permission.isGranted()) {
                     proto.write(PackageProto.UserPermissionsProto.GRANTED_PERMISSIONS,
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 50c1065..3416147 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2313,7 +2313,8 @@
     }
 
     void readInstallPermissionsLPr(TypedXmlPullParser parser,
-            LegacyPermissionState permissionsState) throws IOException, XmlPullParserException {
+            LegacyPermissionState permissionsState, List<UserInfo> users)
+            throws IOException, XmlPullParserException {
         int outerDepth = parser.getDepth();
         int type;
         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -2328,8 +2329,10 @@
                 String name = parser.getAttributeValue(null, ATTR_NAME);
                 final boolean granted = parser.getAttributeBoolean(null, ATTR_GRANTED, true);
                 final int flags = parser.getAttributeIntHex(null, ATTR_FLAGS, 0);
-                permissionsState.putInstallPermissionState(new PermissionState(name, granted,
-                        flags));
+                for (final UserInfo user : users) {
+                    permissionsState.putPermissionState(new PermissionState(name, false, granted,
+                            flags), user.id);
+                }
             } else {
                 Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
                         + parser.getName());
@@ -2338,25 +2341,6 @@
         }
     }
 
-    void writePermissionsLPr(TypedXmlSerializer serializer, Collection<PermissionState> permissionStates)
-            throws IOException {
-        if (permissionStates.isEmpty()) {
-            return;
-        }
-
-        serializer.startTag(null, TAG_PERMISSIONS);
-
-        for (PermissionState permissionState : permissionStates) {
-            serializer.startTag(null, TAG_ITEM);
-            serializer.attributeInterned(null, ATTR_NAME, permissionState.getName());
-            serializer.attributeBoolean(null, ATTR_GRANTED, permissionState.isGranted());
-            serializer.attributeIntHex(null, ATTR_FLAGS, permissionState.getFlags());
-            serializer.endTag(null, TAG_ITEM);
-        }
-
-        serializer.endTag(null, TAG_PERMISSIONS);
-    }
-
     void readUsesStaticLibLPw(TypedXmlPullParser parser, PackageSetting outPs)
             throws IOException, XmlPullParserException {
         String libName = parser.getAttributeValue(null, ATTR_NAME);
@@ -2572,8 +2556,6 @@
                 serializer.attribute(null, ATTR_NAME, usr.name);
                 serializer.attributeInt(null, "userId", usr.userId);
                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
-                writePermissionsLPr(serializer, usr.getLegacyPermissionState()
-                        .getInstallPermissionStates());
                 serializer.endTag(null, "shared-user");
             }
 
@@ -2898,12 +2880,6 @@
 
         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
 
-        // If this is a shared user, the permissions will be written there.
-        if (pkg.sharedUser == null) {
-            writePermissionsLPr(serializer, pkg.getLegacyPermissionState()
-                    .getInstallPermissionStates());
-        }
-
         serializer.endTag(null, "updated-package");
     }
 
@@ -2991,9 +2967,6 @@
                     serializer, "install-initiator-sigs", mPastSignatures);
         }
 
-        writePermissionsLPr(serializer,
-                pkg.getLegacyPermissionState().getInstallPermissionStates());
-
         writeSigningKeySetLPr(serializer, pkg.keySetData);
         writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
         writeKeySetAliasesLPr(serializer, pkg.keySetData);
@@ -3097,13 +3070,13 @@
 
                 String tagName = parser.getName();
                 if (tagName.equals("package")) {
-                    readPackageLPw(parser);
+                    readPackageLPw(parser, users);
                 } else if (tagName.equals("permissions")) {
                     mPermissions.readPermissions(parser);
                 } else if (tagName.equals("permission-trees")) {
                     mPermissions.readPermissionTrees(parser);
                 } else if (tagName.equals("shared-user")) {
-                    readSharedUserLPw(parser);
+                    readSharedUserLPw(parser, users);
                 } else if (tagName.equals("preferred-packages")) {
                     // no longer used.
                 } else if (tagName.equals("preferred-activities")) {
@@ -3121,7 +3094,7 @@
                 } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
                     readDefaultAppsLPw(parser, 0);
                 } else if (tagName.equals("updated-package")) {
-                    readDisabledSysPackageLPw(parser);
+                    readDisabledSysPackageLPw(parser, users);
                 } else if (tagName.equals("renamed-package")) {
                     String nname = parser.getAttributeValue(null, "new");
                     String oname = parser.getAttributeValue(null, "old");
@@ -3627,7 +3600,7 @@
         }
     }
 
-    private void readDisabledSysPackageLPw(TypedXmlPullParser parser)
+    private void readDisabledSysPackageLPw(TypedXmlPullParser parser, List<UserInfo> users)
             throws XmlPullParserException, IOException {
         String name = parser.getAttributeValue(null, ATTR_NAME);
         String realName = parser.getAttributeValue(null, "realName");
@@ -3676,7 +3649,7 @@
             }
 
             if (parser.getName().equals(TAG_PERMISSIONS)) {
-                readInstallPermissionsLPr(parser, ps.getLegacyPermissionState());
+                readInstallPermissionsLPr(parser, ps.getLegacyPermissionState(), users);
             } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) {
                 readUsesStaticLibLPw(parser, ps);
             } else {
@@ -3693,7 +3666,7 @@
     private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
     private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
 
-    private void readPackageLPw(TypedXmlPullParser parser)
+    private void readPackageLPw(TypedXmlPullParser parser, List<UserInfo> users)
             throws XmlPullParserException, IOException {
         String name = null;
         String realName = null;
@@ -3935,7 +3908,7 @@
                     packageSetting.signatures.readXml(parser, mPastSignatures);
                 } else if (tagName.equals(TAG_PERMISSIONS)) {
                     readInstallPermissionsLPr(parser,
-                            packageSetting.getLegacyPermissionState());
+                            packageSetting.getLegacyPermissionState(), users);
                     packageSetting.installPermissionsFixed = true;
                 } else if (tagName.equals("proper-signing-keyset")) {
                     long id = parser.getAttributeLong(null, "identifier");
@@ -4112,7 +4085,7 @@
         }
     }
 
-    private void readSharedUserLPw(TypedXmlPullParser parser)
+    private void readSharedUserLPw(TypedXmlPullParser parser, List<UserInfo> users)
             throws XmlPullParserException, IOException {
         String name = null;
         int pkgFlags = 0;
@@ -4156,7 +4129,7 @@
                 if (tagName.equals("sigs")) {
                     su.signatures.readXml(parser, mPastSignatures);
                 } else if (tagName.equals("perms")) {
-                    readInstallPermissionsLPr(parser, su.getLegacyPermissionState());
+                    readInstallPermissionsLPr(parser, su.getLegacyPermissionState(), users);
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Unknown element under <shared-user>: " + parser.getName());
@@ -4979,7 +4952,7 @@
                 dumpGidsLPr(pw, prefix + "    ", mPermissionDataProvider.getGidsForUid(
                         UserHandle.getUid(user.id, ps.appId)));
                 dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
-                        .getRuntimePermissionStates(user.id), dumpAll);
+                        .getPermissionStates(user.id), dumpAll);
             }
 
             String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
@@ -5154,7 +5127,7 @@
                     final int[] gids = mPermissionDataProvider.getGidsForUid(UserHandle.getUid(
                             userId, su.userId));
                     final Collection<PermissionState> permissions =
-                            permissionsState.getRuntimePermissionStates(userId);
+                            permissionsState.getPermissionStates(userId);
                     if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
                         pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
                         dumpGidsLPr(pw, prefix + "  ", gids);
@@ -5215,9 +5188,19 @@
 
     void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
             Collection<PermissionState> permissionStates, boolean dumpAll) {
-        if (!permissionStates.isEmpty() || dumpAll) {
+        boolean hasRuntimePermissions = false;
+        for (PermissionState permissionState : permissionStates) {
+            if (permissionState.isRuntime()) {
+                hasRuntimePermissions = true;
+                break;
+            }
+        }
+        if (hasRuntimePermissions || dumpAll) {
             pw.print(prefix); pw.println("runtime permissions:");
             for (PermissionState permissionState : permissionStates) {
+                if (!permissionState.isRuntime()) {
+                    continue;
+                }
                 if (permissionNames != null
                         && !permissionNames.contains(permissionState.getName())) {
                     continue;
@@ -5256,11 +5239,21 @@
 
     void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
             LegacyPermissionState permissionsState) {
-        Collection<PermissionState> permissionStates =
-                permissionsState.getInstallPermissionStates();
-        if (!permissionStates.isEmpty()) {
+        Collection<PermissionState> permissionStates = permissionsState.getPermissionStates(
+                UserHandle.USER_SYSTEM);
+        boolean hasInstallPermissions = false;
+        for (PermissionState permissionState : permissionStates) {
+            if (!permissionState.isRuntime()) {
+                hasInstallPermissions = true;
+                break;
+            }
+        }
+        if (hasInstallPermissions) {
             pw.print(prefix); pw.println("install permissions:");
             for (PermissionState permissionState : permissionStates) {
+                if (permissionState.isRuntime()) {
+                    continue;
+                }
                 if (permissionNames != null
                         && !permissionNames.contains(permissionState.getName())) {
                     continue;
@@ -5295,7 +5288,7 @@
         }
     }
 
-    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
+    public void writePermissionStateForUserLPr(int userId, boolean sync) {
         if (sync) {
             mRuntimePermissionsPersistence.writeStateForUserSyncLPr(userId);
         } else {
@@ -5530,7 +5523,7 @@
         private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState(
                 @NonNull LegacyPermissionState permissionsState, @UserIdInt int userId) {
             Collection<PermissionState> permissionStates =
-                    permissionsState.getRuntimePermissionStates(userId);
+                    permissionsState.getPermissionStates(userId);
             List<RuntimePermissionsState.PermissionState> permissions = new ArrayList<>();
             for (PermissionState permissionState : permissionStates) {
                 RuntimePermissionsState.PermissionState permission =
@@ -5590,6 +5583,7 @@
                 if (permissions != null) {
                     readPermissionsStateLpr(permissions, packageSetting.getLegacyPermissionState(),
                             userId);
+                    packageSetting.installPermissionsFixed = true;
                 } else if (packageSetting.sharedUser == null && !isUpgradeToR) {
                     Slog.w(TAG, "Missing permission state for package: " + packageName);
                     packageSetting.getLegacyPermissionState().setMissing(true, userId);
@@ -5624,7 +5618,7 @@
                 String name = permission.getName();
                 boolean granted = permission.isGranted();
                 int flags = permission.getFlags();
-                permissionsState.putRuntimePermissionState(new PermissionState(name, granted,
+                permissionsState.putPermissionState(new PermissionState(name, true, granted,
                         flags), userId);
             }
         }
@@ -5646,7 +5640,7 @@
 
             try {
                 final TypedXmlPullParser parser = Xml.resolvePullParser(in);
-                parseRuntimePermissionsLPr(parser, userId);
+                parseLegacyRuntimePermissionsLPr(parser, userId);
 
             } catch (XmlPullParserException | IOException e) {
                 throw new IllegalStateException("Failed parsing permissions file: "
@@ -5659,7 +5653,7 @@
         // Private internals
 
         @GuardedBy("Settings.this.mLock")
-        private void parseRuntimePermissionsLPr(TypedXmlPullParser parser, int userId)
+        private void parseLegacyRuntimePermissionsLPr(TypedXmlPullParser parser, int userId)
                 throws IOException, XmlPullParserException {
             final int outerDepth = parser.getDepth();
             int type;
@@ -5687,7 +5681,7 @@
                             XmlUtils.skipCurrentTag(parser);
                             continue;
                         }
-                        parsePermissionsLPr(parser, ps.getLegacyPermissionState(), userId);
+                        parseLegacyPermissionsLPr(parser, ps.getLegacyPermissionState(), userId);
                     } break;
 
                     case TAG_SHARED_USER: {
@@ -5698,13 +5692,13 @@
                             XmlUtils.skipCurrentTag(parser);
                             continue;
                         }
-                        parsePermissionsLPr(parser, sus.getLegacyPermissionState(), userId);
+                        parseLegacyPermissionsLPr(parser, sus.getLegacyPermissionState(), userId);
                     } break;
                 }
             }
         }
 
-        private void parsePermissionsLPr(TypedXmlPullParser parser,
+        private void parseLegacyPermissionsLPr(TypedXmlPullParser parser,
                 LegacyPermissionState permissionsState, int userId)
                 throws IOException, XmlPullParserException {
             final int outerDepth = parser.getDepth();
@@ -5722,7 +5716,7 @@
                                 parser.getAttributeBoolean(null, ATTR_GRANTED, true);
                         final int flags =
                                 parser.getAttributeIntHex(null, ATTR_FLAGS, 0);
-                        permissionsState.putRuntimePermissionState(new PermissionState(name,
+                        permissionsState.putPermissionState(new PermissionState(name, true,
                                 granted, flags), userId);
                     }
                     break;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 19a94b3..314510b 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3843,7 +3843,6 @@
      */
     @Override
     public boolean removeUser(@UserIdInt int userId) {
-        Slog.i(LOG_TAG, "removeUser u" + userId, new Exception());
         checkManageOrCreateUsersPermission("Only the system can remove users");
 
         final String restriction = getUserRemovalRestriction(userId);
@@ -3968,13 +3967,16 @@
     }
 
     @Override
-    public @UserManager.RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId) {
-        Slog.i(LOG_TAG, "removeUserOrSetEphemeral u" + userId);
+    public @UserManager.RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId,
+            boolean evenWhenDisallowed) {
         checkManageOrCreateUsersPermission("Only the system can remove users");
-        final String restriction = getUserRemovalRestriction(userId);
-        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
-            Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
-            return UserManager.REMOVE_RESULT_ERROR;
+
+        if (!evenWhenDisallowed) {
+            final String restriction = getUserRemovalRestriction(userId);
+            if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
+                Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
+                return UserManager.REMOVE_RESULT_ERROR;
+            }
         }
         if (userId == UserHandle.USER_SYSTEM) {
             Slog.e(LOG_TAG, "System user cannot be removed.");
@@ -4003,7 +4005,7 @@
                 final int currentUser = ActivityManager.getCurrentUser();
                 if (currentUser != userId) {
                     // Attempt to remove the user. This will fail if the user is the current user
-                    if (removeUser(userId)) {
+                    if (removeUserUnchecked(userId)) {
                         return UserManager.REMOVE_RESULT_REMOVED;
                     }
                 }
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index 252ba60..6e6d7c3 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -327,17 +327,17 @@
         final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
 
         // Check whether all allowlisted packages are indeed on the system.
-        final String notPresentFmt = "%s is whitelisted but not present.";
-        final String notSystemFmt = "%s is whitelisted and present but not a system package.";
-        final String overlayPackageFmt = "%s is whitelisted but it's auto-generated RRO package.";
+        final String notPresentFmt = "%s is allowlisted but not present.";
+        final String notSystemFmt = "%s is allowlisted and present but not a system package.";
+        final String overlayFmt = "%s is allowlisted unnecessarily since it's a static overlay.";
         for (String pkgName : allWhitelistedPackages) {
             final AndroidPackage pkg = pmInt.getPackage(pkgName);
             if (pkg == null) {
                 warnings.add(String.format(notPresentFmt, pkgName));
             } else if (!pkg.isSystem()) {
                 warnings.add(String.format(notSystemFmt, pkgName));
-            } else if (isAutoGeneratedRRO(pkg)) {
-                warnings.add(String.format(overlayPackageFmt, pkgName));
+            } else if (shouldUseOverlayTargetName(pkg)) {
+                warnings.add(String.format(overlayFmt, pkgName));
             }
         }
         return warnings;
@@ -363,7 +363,7 @@
             if (!pkg.isSystem()) return;
             final String pkgName = pkg.getManifestPackageName();
             if (!allWhitelistedPackages.contains(pkgName)
-                    && !isAutoGeneratedRRO(pmInt.getPackage(pkgName))) {
+                    && !shouldUseOverlayTargetName(pmInt.getPackage(pkgName))) {
                 errors.add(String.format(logMessageFmt, pkgName));
             }
         });
@@ -413,22 +413,13 @@
     }
 
     /**
-     * Whether package name has auto-generated RRO package name suffix.
+     * Returns whether the package is a static overlay, whose installation should depend on the
+     * allowlisting of the overlay's target's package name, rather than of its own package name.
+     *
+     * @param pkg A package (which need not be an overlay)
      */
-    @VisibleForTesting
-    static boolean hasAutoGeneratedRROSuffix(String name) {
-        return name.endsWith(".auto_generated_rro_product__")
-                // TODO(b/172956245): temporary workaround until OEMs can customize name
-                || name.endsWith("carui.rro") || name.endsWith("carui.overlayable.rro")
-                || name.endsWith(".auto_generated_rro_vendor__");
-    }
-
-    /**
-     * Whether the package is auto-generated RRO package.
-     */
-    private static boolean isAutoGeneratedRRO(AndroidPackage pkg) {
-        return pkg.isOverlay()
-                && (hasAutoGeneratedRROSuffix(pkg.getManifestPackageName()));
+    private static boolean shouldUseOverlayTargetName(AndroidPackage pkg) {
+        return pkg.isOverlayIsStatic();
     }
 
     /** See {@link #isEnforceMode()}. */
@@ -542,18 +533,8 @@
     static boolean shouldInstallPackage(AndroidPackage sysPkg,
             @NonNull ArrayMap<String, Long> userTypeWhitelist,
             @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist) {
-        final String pkgName;
-        if (isAutoGeneratedRRO(sysPkg)) {
-            pkgName = sysPkg.getOverlayTarget();
-            if (DEBUG) {
-                Slog.i(TAG, "shouldInstallPackage(): " + sysPkg.getManifestPackageName()
-                        + " is auto-generated RRO package, will look for overlay system package: "
-                        + pkgName);
-            }
-        } else {
-            pkgName = sysPkg.getManifestPackageName();
-        }
-
+        final String pkgName = shouldUseOverlayTargetName(sysPkg) ?
+                sysPkg.getOverlayTarget() : sysPkg.getManifestPackageName();
         return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName))
                 || userWhitelist.contains(pkgName);
     }
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java
index 72d7628..92f22a4 100644
--- a/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -105,28 +104,14 @@
     }
 
     /**
-     * Put a install permission state.
-     *
-     * @param permissionState the permission state
-     */
-    public void putInstallPermissionState(@NonNull PermissionState permissionState) {
-        putPermissionState(permissionState, UserHandle.USER_ALL);
-    }
-
-    /**
-     * Put a runtime permission state for a user.
+     * Put a permission state for a user.
      *
      * @param permissionState the permission state
      * @param userId the user ID
      */
-    public void putRuntimePermissionState(@NonNull PermissionState permissionState,
+    public void putPermissionState(@NonNull PermissionState permissionState,
             @UserIdInt int userId) {
         checkUserId(userId);
-        putPermissionState(permissionState, userId);
-    }
-
-    private void putPermissionState(@NonNull PermissionState permissionState,
-            @UserIdInt int userId) {
         UserState userState = mUserStates.get(userId);
         if (userState == null) {
             userState = new UserState();
@@ -157,29 +142,14 @@
     }
 
     /**
-     * Get all the install permission states.
-     *
-     * @return the install permission states
-     */
-    @NonNull
-    public Collection<PermissionState> getInstallPermissionStates() {
-        return getPermissionStates(UserHandle.USER_ALL);
-    }
-
-    /**
      * Get all the runtime permission states for a user.
      *
      * @param userId the user ID
      * @return the runtime permission states
      */
     @NonNull
-    public Collection<PermissionState> getRuntimePermissionStates(@UserIdInt int userId) {
+    public Collection<PermissionState> getPermissionStates(@UserIdInt int userId) {
         checkUserId(userId);
-        return getPermissionStates(userId);
-    }
-
-    @NonNull
-    private Collection<PermissionState> getPermissionStates(@UserIdInt int userId) {
         final UserState userState = mUserStates.get(userId);
         if (userState == null) {
             return Collections.emptyList();
@@ -265,6 +235,8 @@
         @NonNull
         private final String mName;
 
+        private final boolean mRuntime;
+
         private final boolean mGranted;
 
         private final int mFlags;
@@ -273,17 +245,20 @@
          * Create a new instance of this class.
          *
          * @param name the name of the permission
+         * @param runtime whether the permission is runtime
          * @param granted whether the permission is granted
          * @param flags the permission flags
          */
-        public PermissionState(@NonNull String name, boolean granted, int flags) {
+        public PermissionState(@NonNull String name, boolean runtime, boolean granted, int flags) {
             mName = name;
+            mRuntime = runtime;
             mGranted = granted;
             mFlags = flags;
         }
 
         private PermissionState(@NonNull PermissionState other) {
             mName = other.mName;
+            mRuntime = other.mRuntime;
             mGranted = other.mGranted;
             mFlags = other.mFlags;
         }
@@ -299,6 +274,15 @@
         }
 
         /**
+         * Get whether the permission is a runtime permission.
+         *
+         * @return whether the permission is a runtime permission.
+         */
+        public boolean isRuntime() {
+            return mRuntime;
+        }
+
+        /**
          * Get whether the permission is granted.
          *
          * @return whether the permission is granted
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 8f42289..2a646b5 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3965,8 +3965,7 @@
             if (!usedPermissions.contains(permissionState.getName())) {
                 Permission bp = mRegistry.getPermission(permissionState.getName());
                 if (bp != null) {
-                    if (uidState.removePermissionState(bp.getName())
-                            && permissionState.isRuntime()) {
+                    if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {
                         runtimePermissionChanged = true;
                     }
                 }
@@ -4573,9 +4572,7 @@
                     uidState.reset();
                     uidState.setMissing(legacyState.isMissing(userId));
                     readLegacyPermissionStatesLocked(uidState,
-                            legacyState.getInstallPermissionStates());
-                    readLegacyPermissionStatesLocked(uidState,
-                            legacyState.getRuntimePermissionStates(userId));
+                            legacyState.getPermissionStates(userId));
                 }
             }
         });
@@ -4634,12 +4631,9 @@
 
                         final LegacyPermissionState.PermissionState legacyPermissionState =
                                 new LegacyPermissionState.PermissionState(permissionState.getName(),
+                                        permissionState.getPermission().isRuntime(),
                                         permissionState.isGranted(), permissionState.getFlags());
-                        if (permissionState.isRuntime()) {
-                            legacyState.putRuntimePermissionState(legacyPermissionState, userId);
-                        } else {
-                            legacyState.putInstallPermissionState(legacyPermissionState);
-                        }
+                        legacyState.putPermissionState(legacyPermissionState, userId);
                     }
                 }
             }
@@ -4904,12 +4898,9 @@
 
                     final LegacyPermissionState.PermissionState legacyPermissionState =
                             new LegacyPermissionState.PermissionState(permissionState.getName(),
+                                    permissionState.getPermission().isRuntime(),
                                     permissionState.isGranted(), permissionState.getFlags());
-                    if (permissionState.isRuntime()) {
-                        legacyState.putRuntimePermissionState(legacyPermissionState, userId);
-                    } else if (userId == UserHandle.USER_SYSTEM) {
-                        legacyState.putInstallPermissionState(legacyPermissionState);
-                    }
+                    legacyState.putPermissionState(legacyPermissionState, userId);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionState.java b/services/core/java/com/android/server/pm/permission/PermissionState.java
index 12f29d0..9ad8a05 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionState.java
@@ -32,9 +32,6 @@
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
-    private boolean mRuntime;
-
-    @GuardedBy("mLock")
     private boolean mGranted;
 
     @GuardedBy("mLock")
@@ -66,12 +63,6 @@
         return mPermission.computeGids(userId);
     }
 
-    public boolean isRuntime() {
-        synchronized (mLock) {
-            return mPermission.isRuntime();
-        }
-    }
-
     public boolean isGranted() {
         synchronized (mLock) {
             return mGranted;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 69484b1..c073b43 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -447,25 +447,8 @@
     volatile int mPowerKeyPressCounter;
     volatile boolean mEndCallKeyHandled;
     volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
-
-    /**
-     * {@code true} if the device is entering a low-power state; {@code false otherwise}.
-     *
-     * <p>This differs from {@link #mRequestedOrSleepingDefaultDisplay} which tracks the power state
-     * of the {@link #mDefaultDisplay default display} versus the power state of the entire device.
-     */
-    volatile boolean mDeviceGoingToSleep;
-
-    /**
-     * {@code true} if the {@link #mDefaultDisplay default display} is entering or was requested to
-     * enter a low-power state; {@code false otherwise}.
-     *
-     * <p>This differs from {@link #mDeviceGoingToSleep} which tracks the power state of the entire
-     * device versus the power state of the {@link #mDefaultDisplay default display}.
-     */
-    // TODO(b/178103325): Track sleep/requested sleep for every display.
-    volatile boolean mRequestedOrSleepingDefaultDisplay;
-
+    volatile boolean mGoingToSleep;
+    volatile boolean mRequestedOrGoingToSleep;
     volatile boolean mRecentsVisible;
     volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true;
     volatile boolean mPictureInPictureVisible;
@@ -933,7 +916,7 @@
         if (gestureService != null) {
             gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
                     mTmpBoolean);
-            if (mTmpBoolean.value && mRequestedOrSleepingDefaultDisplay) {
+            if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
                 mCameraGestureTriggeredDuringGoingToSleep = true;
             }
         }
@@ -1080,14 +1063,13 @@
                 case SHORT_PRESS_POWER_NOTHING:
                     break;
                 case SHORT_PRESS_POWER_GO_TO_SLEEP:
-                    sleepDefaultDisplayFromPowerButton(eventTime, 0);
+                    goToSleepFromPowerButton(eventTime, 0);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
-                    sleepDefaultDisplayFromPowerButton(eventTime,
-                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+                    goToSleepFromPowerButton(eventTime, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
-                    if (sleepDefaultDisplayFromPowerButton(eventTime,
+                    if (goToSleepFromPowerButton(eventTime,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) {
                         launchHomeFromHotKey(DEFAULT_DISPLAY);
                     }
@@ -1115,11 +1097,11 @@
     }
 
     /**
-     * Sends the default display to sleep as a result of a power button press.
+     * Sends the device to sleep as a result of a power button press.
      *
-     * @return True if the device was sent to sleep, false if the device did not sleep.
+     * @return True if the was device was sent to sleep, false if sleep was suppressed.
      */
-    private boolean sleepDefaultDisplayFromPowerButton(long eventTime, int flags) {
+    private boolean goToSleepFromPowerButton(long eventTime, int flags) {
         // Before we actually go to sleep, we check the last wakeup reason.
         // If the device very recently woke up from a gesture (like user lifting their device)
         // then ignore the sleep instruction. This is because users have developed
@@ -1139,12 +1121,12 @@
             }
         }
 
-        sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
+        goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
         return true;
     }
 
-    private void sleepDefaultDisplay(long eventTime, int reason, int flags) {
-        mRequestedOrSleepingDefaultDisplay = true;
+    private void goToSleep(long eventTime, int reason, int flags) {
+        mRequestedOrGoingToSleep = true;
         mPowerManager.goToSleep(eventTime, reason, flags);
     }
 
@@ -1181,8 +1163,7 @@
                             Settings.Global.THEATER_MODE_ON, 1);
 
                     if (mGoToSleepOnButtonPressTheaterMode && interactive) {
-                        sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
-                                0);
+                        goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     }
                 }
                 break;
@@ -1290,7 +1271,7 @@
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
                 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
-                sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+                goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
                 break;
         }
     }
@@ -3705,7 +3686,7 @@
                             }
                             if ((mEndcallBehavior
                                     & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
-                                sleepDefaultDisplay(event.getEventTime(),
+                                goToSleep(event.getEventTime(),
                                         PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                                 isWakeKey = false;
                             }
@@ -3748,12 +3729,10 @@
                 // Any activity on the power button stops the accessibility shortcut
                 result &= ~ACTION_PASS_TO_USER;
                 isWakeKey = false; // wake-up will be handled separately
-                final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
-                final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
                 if (down) {
-                    interceptPowerKeyDown(event, interactiveAndOn);
+                    interceptPowerKeyDown(event, interactive);
                 } else {
-                    interceptPowerKeyUp(event, interactiveAndOn, canceled);
+                    interceptPowerKeyUp(event, interactive, canceled);
                 }
                 break;
             }
@@ -4263,7 +4242,8 @@
                                     pmSleepReason)) + ")");
         }
 
-        mDeviceGoingToSleep = true;
+        mGoingToSleep = true;
+        mRequestedOrGoingToSleep = true;
 
         if (mKeyguardDelegate != null) {
             mKeyguardDelegate.onStartedGoingToSleep(pmSleepReason);
@@ -4282,7 +4262,8 @@
         }
         MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
 
-        mDeviceGoingToSleep = false;
+        mGoingToSleep = false;
+        mRequestedOrGoingToSleep = false;
         mDefaultDisplayPolicy.setAwake(false);
 
         // We must get this work done here because the power manager will drop
@@ -4432,7 +4413,6 @@
 
         if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");
 
-        mRequestedOrSleepingDefaultDisplay = false;
         updateScreenOffSleepToken(true);
         mDefaultDisplayPolicy.screenTurnedOff();
         synchronized (mLock) {
@@ -4499,7 +4479,6 @@
             return;
         }
 
-        mRequestedOrSleepingDefaultDisplay = true;
         mWindowManagerFuncs.screenTurningOff(screenOffListener);
         synchronized (mLock) {
             if (mKeyguardDelegate != null) {
@@ -4585,7 +4564,7 @@
 
     @Override
     public boolean okToAnimate() {
-        return mDefaultDisplayPolicy.isAwake() && !mDeviceGoingToSleep;
+        return mDefaultDisplayPolicy.isAwake() && !mGoingToSleep;
     }
 
     /** {@inheritDoc} */
@@ -4961,7 +4940,7 @@
                     mWindowManagerFuncs.lockDeviceNow();
                     break;
                 case LID_BEHAVIOR_SLEEP:
-                    sleepDefaultDisplay(SystemClock.uptimeMillis(),
+                    goToSleep(SystemClock.uptimeMillis(),
                             PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     break;
@@ -5453,6 +5432,8 @@
                 return "LONG_PRESS_HOME_ALL_APPS";
             case LONG_PRESS_HOME_ASSIST:
                 return "LONG_PRESS_HOME_ASSIST";
+            case LONG_PRESS_HOME_NOTIFICATION_PANEL:
+                return "LONG_PRESS_HOME_NOTIFICATION_PANEL";
             default:
                 return Integer.toString(behavior);
         }
diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleStateProviderImpl.java b/services/core/java/com/android/server/policy/role/RoleServicePlatformHelperImpl.java
similarity index 80%
rename from services/core/java/com/android/server/policy/role/LegacyRoleStateProviderImpl.java
rename to services/core/java/com/android/server/policy/role/RoleServicePlatformHelperImpl.java
index 097f332..c2596c7 100644
--- a/services/core/java/com/android/server/policy/role/LegacyRoleStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/role/RoleServicePlatformHelperImpl.java
@@ -27,22 +27,27 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
+import android.content.pm.Signature;
 import android.os.Environment;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.PackageUtils;
 import android.util.Slog;
 import android.util.Xml;
 
 import com.android.internal.R;
+import com.android.internal.util.CollectionUtils;
 import com.android.server.LocalServices;
-import com.android.server.role.LegacyRoleStateProvider;
+import com.android.server.role.RoleServicePlatformHelper;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -53,10 +58,10 @@
 import java.util.Set;
 
 /**
- * Implementation to provide legacy role state.
+ * Implementation of {@link RoleServicePlatformHelper}.
  */
-public class LegacyRoleStateProviderImpl implements LegacyRoleStateProvider {
-    private static final String LOG_TAG = "LegacyRoleState";
+public class RoleServicePlatformHelperImpl implements RoleServicePlatformHelper {
+    private static final String LOG_TAG = RoleServicePlatformHelperImpl.class.getSimpleName();
 
     private static final String ROLES_FILE_NAME = "roles.xml";
 
@@ -68,7 +73,7 @@
     @NonNull
     private final Context mContext;
 
-    public LegacyRoleStateProviderImpl(@NonNull Context context) {
+    public RoleServicePlatformHelperImpl(@NonNull Context context) {
         mContext = context;
     }
 
@@ -288,4 +293,44 @@
         }
         return Objects.equals(packageName, resolveInfo.activityInfo.packageName);
     }
+
+    @NonNull
+    @Override
+    public String computePackageStateHash(@UserIdInt int userId) {
+        PackageManagerInternal packageManagerInternal = LocalServices.getService(
+                PackageManagerInternal.class);
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
+        packageManagerInternal.forEachInstalledPackage(pkg -> {
+            try {
+                dataOutputStream.writeUTF(pkg.getPackageName());
+                dataOutputStream.writeLong(pkg.getLongVersionCode());
+                dataOutputStream.writeInt(packageManagerInternal.getApplicationEnabledState(
+                        pkg.getPackageName(), userId));
+
+                final ArraySet<String> enabledComponents =
+                        packageManagerInternal.getEnabledComponents(pkg.getPackageName(), userId);
+                final int enabledComponentsSize = CollectionUtils.size(enabledComponents);
+                dataOutputStream.writeInt(enabledComponentsSize);
+                for (int i = 0; i < enabledComponentsSize; i++) {
+                    dataOutputStream.writeUTF(enabledComponents.valueAt(i));
+                }
+
+                final ArraySet<String> disabledComponents =
+                        packageManagerInternal.getDisabledComponents(pkg.getPackageName(), userId);
+                final int disabledComponentsSize = CollectionUtils.size(disabledComponents);
+                for (int i = 0; i < disabledComponentsSize; i++) {
+                    dataOutputStream.writeUTF(disabledComponents.valueAt(i));
+                }
+
+                for (final Signature signature : pkg.getSigningDetails().signatures) {
+                    dataOutputStream.write(signature.toByteArray());
+                }
+            } catch (IOException e) {
+                // Never happens for ByteArrayOutputStream and DataOutputStream.
+                throw new AssertionError(e);
+            }
+        }, userId);
+        return PackageUtils.computeSha256Digest(byteArrayOutputStream.toByteArray());
+    }
 }
diff --git a/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java b/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java
deleted file mode 100644
index 8ebeea3..0000000
--- a/services/core/java/com/android/server/power/DisplayGroupPowerStateMapper.java
+++ /dev/null
@@ -1,280 +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.power;
-
-import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
-import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
-import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
-import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
-
-import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_ADDED;
-import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_CHANGED;
-import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED;
-
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.os.Handler;
-import android.os.PowerManagerInternal;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.ArrayUtils;
-import com.android.server.display.DisplayGroup;
-
-/**
- * Responsible for creating {@link DisplayPowerRequest}s and associating them with
- * {@link com.android.server.display.DisplayGroup}s.
- *
- * Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
- * which is used to request power state changes to every display in the group.
- */
-public class DisplayGroupPowerStateMapper {
-
-    private static final String TAG = "DisplayPowerRequestMapper";
-
-    /** Lock obtained from {@link PowerManagerService}. */
-    private final Object mLock;
-
-    /** Listener to inform of changes to display groups. */
-    private final DisplayGroupPowerChangeListener mListener;
-
-    /** A mapping from DisplayGroup Id to DisplayGroup information. */
-    @GuardedBy("mLock")
-    private final SparseArray<DisplayGroupInfo> mDisplayGroupInfos = new SparseArray<>();
-
-    /** A cached array of DisplayGroup Ids. */
-    @GuardedBy("mLock")
-    private int[] mDisplayGroupIds;
-
-    private final DisplayManagerInternal.DisplayGroupListener mDisplayGroupListener =
-            new DisplayManagerInternal.DisplayGroupListener() {
-                @Override
-                public void onDisplayGroupAdded(int groupId) {
-                    synchronized (mLock) {
-                        if (mDisplayGroupInfos.contains(groupId)) {
-                            Slog.e(TAG, "Tried to add already existing group:" + groupId);
-                            return;
-                        }
-                        // For now, only the default group supports sandman.
-                        final boolean supportsSandman = groupId == DisplayGroup.DEFAULT;
-                        final DisplayGroupInfo displayGroupInfo = new DisplayGroupInfo(
-                                new DisplayPowerRequest(),
-                                getGlobalWakefulnessLocked(), /* ready= */ false,
-                                supportsSandman);
-                        mDisplayGroupInfos.append(groupId, displayGroupInfo);
-                        mDisplayGroupIds = ArrayUtils.appendInt(mDisplayGroupIds, groupId);
-                        mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_ADDED, groupId);
-                    }
-                }
-
-                @Override
-                public void onDisplayGroupRemoved(int groupId) {
-                    synchronized (mLock) {
-                        if (!mDisplayGroupInfos.contains(groupId)) {
-                            Slog.e(TAG, "Tried to remove non-existent group:" + groupId);
-                            return;
-                        }
-                        mDisplayGroupInfos.delete(groupId);
-                        mDisplayGroupIds = ArrayUtils.removeInt(mDisplayGroupIds, groupId);
-                        mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_REMOVED, groupId);
-                    }
-                }
-
-                @Override
-                public void onDisplayGroupChanged(int groupId) {
-                    synchronized (mLock) {
-                        mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_CHANGED, groupId);
-                    }
-                }
-            };
-
-    DisplayGroupPowerStateMapper(Object lock, DisplayManagerInternal displayManagerInternal,
-            DisplayGroupPowerChangeListener listener) {
-        mLock = lock;
-        mListener = listener;
-        displayManagerInternal.registerDisplayGroupListener(mDisplayGroupListener);
-
-        final DisplayGroupInfo displayGroupInfo = new DisplayGroupInfo(
-                new DisplayPowerRequest(), WAKEFULNESS_AWAKE, /* ready= */
-                false, /* supportsSandman= */ true);
-        mDisplayGroupInfos.append(DisplayGroup.DEFAULT, displayGroupInfo);
-        mDisplayGroupIds = new int[]{DisplayGroup.DEFAULT};
-    }
-
-    DisplayPowerRequest getPowerRequestLocked(int groupId) {
-        return mDisplayGroupInfos.get(groupId).displayPowerRequest;
-    }
-
-    int[] getDisplayGroupIdsLocked() {
-        return mDisplayGroupIds;
-    }
-
-    int getWakefulnessLocked(int groupId) {
-        return mDisplayGroupInfos.get(groupId).wakefulness;
-    }
-
-    void setLastPowerOnTimeLocked(int groupId, long eventTime) {
-        mDisplayGroupInfos.get(groupId).lastPowerOnTime = eventTime;
-    }
-
-    long getLastPowerOnTimeLocked(int groupId) {
-        return mDisplayGroupInfos.get(groupId).lastPowerOnTime;
-    }
-
-    /**
-     * Returns the amalgamated wakefulness of all {@link DisplayGroup DisplayGroups}.
-     *
-     * <p>This will be the highest wakeful state of all {@link DisplayGroup DisplayGroups}; ordered
-     * from highest to lowest:
-     * <ol>
-     *     <li>{@link PowerManagerInternal#WAKEFULNESS_AWAKE}
-     *     <li>{@link PowerManagerInternal#WAKEFULNESS_DREAMING}
-     *     <li>{@link PowerManagerInternal#WAKEFULNESS_DOZING}
-     *     <li>{@link PowerManagerInternal#WAKEFULNESS_ASLEEP}
-     * </ol>
-     */
-    int getGlobalWakefulnessLocked() {
-        final int size = mDisplayGroupInfos.size();
-        int deviceWakefulness = WAKEFULNESS_ASLEEP;
-        for (int i = 0; i < size; i++) {
-            final int wakefulness = mDisplayGroupInfos.valueAt(i).wakefulness;
-            if (wakefulness == WAKEFULNESS_AWAKE) {
-                return WAKEFULNESS_AWAKE;
-            } else if (wakefulness == WAKEFULNESS_DREAMING
-                    && (deviceWakefulness == WAKEFULNESS_ASLEEP
-                    || deviceWakefulness == WAKEFULNESS_DOZING)) {
-                deviceWakefulness = WAKEFULNESS_DREAMING;
-            } else if (wakefulness == WAKEFULNESS_DOZING
-                    && deviceWakefulness == WAKEFULNESS_ASLEEP) {
-                deviceWakefulness = WAKEFULNESS_DOZING;
-            }
-        }
-
-        return deviceWakefulness;
-    }
-
-    /**
-     * Sets the {@code wakefulness} value for the {@link DisplayGroup} specified by the provided
-     * {@code groupId}.
-     *
-     * @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
-     */
-    boolean setWakefulnessLocked(int groupId, int wakefulness) {
-        final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
-        if (displayGroupInfo.wakefulness != wakefulness) {
-            displayGroupInfo.wakefulness = wakefulness;
-            return true;
-        }
-
-        return false;
-    }
-
-    boolean isSandmanSummoned(int groupId) {
-        return mDisplayGroupInfos.get(groupId).sandmanSummoned;
-    }
-
-    boolean isSandmanSupported(int groupId) {
-        return mDisplayGroupInfos.get(groupId).supportsSandman;
-    }
-
-    /**
-     * Sets whether or not the sandman is summoned for the given {@code groupId}.
-     *
-     * @param groupId         Signifies the DisplayGroup for which to summon or unsummon the
-     *                        sandman.
-     * @param sandmanSummoned {@code true} to summon the sandman; {@code false} to unsummon.
-     */
-    void setSandmanSummoned(int groupId, boolean sandmanSummoned) {
-        final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
-        displayGroupInfo.sandmanSummoned = displayGroupInfo.supportsSandman && sandmanSummoned;
-    }
-
-    /**
-     * Returns {@code true} if every display in the specified group has its requested state matching
-     * its actual state.
-     *
-     * @param groupId The identifier for the display group to check for readiness.
-     */
-    boolean isReady(int groupId) {
-        return mDisplayGroupInfos.get(groupId).ready;
-    }
-
-    /** Returns {@code true} if every display has its requested state matching its actual state. */
-    boolean areAllDisplaysReadyLocked() {
-        final int size = mDisplayGroupInfos.size();
-        for (int i = 0; i < size; i++) {
-            if (!mDisplayGroupInfos.valueAt(i).ready) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Sets whether the displays specified by the provided {@code groupId} are all ready.
-     *
-     * <p>A display is ready if its reported
-     * {@link DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() actual state} matches
-     * its {@link DisplayManagerInternal#requestPowerState requested state}.
-     *
-     * @param groupId The identifier for the display group.
-     * @param ready   {@code true} if every display in the group is ready; otherwise {@code false}.
-     * @return {@code true} if the ready state changed; otherwise {@code false}.
-     */
-    boolean setDisplayGroupReadyLocked(int groupId, boolean ready) {
-        final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
-        if (displayGroupInfo.ready != ready) {
-            displayGroupInfo.ready = ready;
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Interface through which an interested party may be informed of {@link DisplayGroup} events.
-     */
-    interface DisplayGroupPowerChangeListener {
-        int DISPLAY_GROUP_ADDED = 0;
-        int DISPLAY_GROUP_REMOVED = 1;
-        int DISPLAY_GROUP_CHANGED = 2;
-
-        void onDisplayGroupEventLocked(int event, int groupId);
-    }
-
-    private static final class DisplayGroupInfo {
-        final DisplayPowerRequest displayPowerRequest;
-        int wakefulness;
-        boolean ready;
-        long lastPowerOnTime;
-        boolean sandmanSummoned;
-
-        /** {@code true} if this DisplayGroup supports dreaming; otherwise {@code false}. */
-        boolean supportsSandman;
-
-        DisplayGroupInfo(DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
-                boolean supportsSandman) {
-            this.displayPowerRequest = displayPowerRequest;
-            this.wakefulness = wakefulness;
-            this.ready = ready;
-            this.supportsSandman = supportsSandman;
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java b/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java
new file mode 100644
index 0000000..6477552
--- /dev/null
+++ b/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java
@@ -0,0 +1,122 @@
+/*
+ * 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.power;
+
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.Handler;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.Display;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.display.DisplayGroup;
+
+/**
+ * Responsible for creating {@link DisplayPowerRequest}s and associating them with
+ * {@link com.android.server.display.DisplayGroup}s.
+ *
+ * Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
+ * which is used to request power state changes to every display in the group.
+ */
+class DisplayPowerRequestMapper {
+
+    private final Object mLock = new Object();
+
+    /** A mapping from LogicalDisplay Id to DisplayGroup Id. */
+    @GuardedBy("mLock")
+    private final SparseIntArray mDisplayGroupIds = new SparseIntArray();
+
+    /** A mapping from DisplayGroup Id to DisplayPowerRequest. */
+    @GuardedBy("mLock")
+    private final SparseArray<DisplayPowerRequest> mDisplayPowerRequests = new SparseArray<>();
+
+    private final DisplayManagerInternal mDisplayManagerInternal;
+
+    private final DisplayManager.DisplayListener mDisplayListener =
+            new DisplayManager.DisplayListener() {
+
+                @Override
+                public void onDisplayAdded(int displayId) {
+                    synchronized (mLock) {
+                        if (mDisplayGroupIds.indexOfKey(displayId) >= 0) {
+                            return;
+                        }
+                        final int displayGroupId = mDisplayManagerInternal.getDisplayGroupId(
+                                displayId);
+                        if (!mDisplayPowerRequests.contains(displayGroupId)) {
+                            // A new DisplayGroup was created; create a new DisplayPowerRequest.
+                            mDisplayPowerRequests.append(displayGroupId, new DisplayPowerRequest());
+                        }
+                        mDisplayGroupIds.append(displayId, displayGroupId);
+                    }
+                }
+
+                @Override
+                public void onDisplayRemoved(int displayId) {
+                    synchronized (mLock) {
+                        final int index = mDisplayGroupIds.indexOfKey(displayId);
+                        if (index < 0) {
+                            return;
+                        }
+                        final int displayGroupId = mDisplayGroupIds.valueAt(index);
+                        mDisplayGroupIds.removeAt(index);
+
+                        if (mDisplayGroupIds.indexOfValue(displayGroupId) < 0) {
+                            // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
+                            mDisplayPowerRequests.delete(displayGroupId);
+                        }
+                    }
+                }
+
+                @Override
+                public void onDisplayChanged(int displayId) {
+                    synchronized (mLock) {
+                        final int newDisplayGroupId = mDisplayManagerInternal.getDisplayGroupId(
+                                displayId);
+                        final int oldDisplayGroupId = mDisplayGroupIds.get(displayId);
+
+                        if (!mDisplayPowerRequests.contains(newDisplayGroupId)) {
+                            // A new DisplayGroup was created; create a new DisplayPowerRequest.
+                            mDisplayPowerRequests.append(newDisplayGroupId,
+                                    new DisplayPowerRequest());
+                        }
+                        mDisplayGroupIds.put(displayId, newDisplayGroupId);
+
+                        if (mDisplayGroupIds.indexOfValue(oldDisplayGroupId) < 0) {
+                            // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
+                            mDisplayPowerRequests.delete(oldDisplayGroupId);
+                        }
+                    }
+                }
+            };
+
+    DisplayPowerRequestMapper(DisplayManager displayManager,
+            DisplayManagerInternal displayManagerInternal, Handler handler) {
+        mDisplayManagerInternal = displayManagerInternal;
+        displayManager.registerDisplayListener(mDisplayListener, handler);
+        mDisplayPowerRequests.append(DisplayGroup.DEFAULT, new DisplayPowerRequest());
+        mDisplayGroupIds.append(Display.DEFAULT_DISPLAY, DisplayGroup.DEFAULT);
+    }
+
+    DisplayPowerRequest get(int displayId) {
+        synchronized (mLock) {
+            return mDisplayPowerRequests.get(mDisplayGroupIds.get(displayId));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index f14ff3c..084dc32 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -18,10 +18,6 @@
 
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;
-import static android.os.PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED;
-import static android.os.PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF;
-import static android.os.PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED;
-import static android.os.PowerManager.WAKE_REASON_DISPLAY_GROUP_TURNED_ON;
 import static android.os.PowerManagerInternal.MODE_DEVICE_IDLE;
 import static android.os.PowerManagerInternal.MODE_DISPLAY_INACTIVE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
@@ -46,6 +42,7 @@
 import android.hardware.SensorManager;
 import android.hardware.SystemSensorManager;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.hardware.power.Boost;
@@ -110,7 +107,6 @@
 import com.android.server.UserspaceRebootLogger;
 import com.android.server.Watchdog;
 import com.android.server.am.BatteryStatsService;
-import com.android.server.display.DisplayGroup;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LogicalLight;
 import com.android.server.policy.WindowManagerPolicy;
@@ -180,8 +176,6 @@
     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 << 15;
 
     // Summarizes the state of all active wakelocks.
     private static final int WAKE_LOCK_CPU = 1 << 0;
@@ -303,6 +297,10 @@
     private int mWakefulnessRaw;
     private boolean mWakefulnessChanging;
 
+    // True if the sandman has just been summoned for the first time since entering the
+    // dreaming or dozing state.  Indicates whether a new dream should begin.
+    private boolean mSandmanSummoned;
+
     // True if MSG_SANDMAN has been scheduled.
     private boolean mSandmanScheduled;
 
@@ -353,7 +351,11 @@
 
     // 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;
+    private DisplayPowerRequestMapper mDisplayPowerRequestMapper;
+
+    // True if the display power state has been fully applied, which means the display
+    // is actually on or actually off or whatever was requested.
+    private boolean mDisplayReady;
 
     // The suspend blocker used to keep the CPU alive when an application has acquired
     // a wake lock.
@@ -623,39 +625,6 @@
     // but the DreamService has not yet been told to start (it's an async process).
     private boolean mDozeStartInProgress;
 
-    private final class DisplayGroupPowerChangeListener implements
-            DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener {
-        @Override
-        public void onDisplayGroupEventLocked(int event, int groupId) {
-            final int oldWakefulness = getWakefulnessLocked();
-            final int newWakefulness = mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked();
-            if (oldWakefulness != newWakefulness) {
-                final int reason;
-                switch (newWakefulness) {
-                    case WAKEFULNESS_AWAKE:
-                        reason = event == DISPLAY_GROUP_ADDED ? WAKE_REASON_DISPLAY_GROUP_ADDED
-                                : WAKE_REASON_DISPLAY_GROUP_TURNED_ON;
-                        break;
-                    case WAKEFULNESS_DOZING:
-                        reason = event == DISPLAY_GROUP_REMOVED
-                                ? GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED
-                                : GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF;
-                        break;
-                    default:
-                        reason = 0;
-                }
-
-                setGlobalWakefulnessLocked(
-                        mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked(),
-                        mClock.uptimeMillis(), reason, Process.SYSTEM_UID, Process.SYSTEM_UID,
-                        mContext.getOpPackageName(), "groupId: " + groupId);
-            }
-
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
-            updatePowerStateLocked();
-        }
-    }
-
     private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver {
         @Override
         public void onUserSwitching(@UserIdInt int newUserId) throws RemoteException {
@@ -899,12 +868,6 @@
         void invalidateIsInteractiveCaches() {
             PowerManager.invalidateIsInteractiveCaches();
         }
-
-        DisplayGroupPowerStateMapper createDisplayPowerRequestMapper(Object lock,
-                DisplayManagerInternal displayManagerInternal,
-                DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener listener) {
-            return new DisplayGroupPowerStateMapper(lock, displayManagerInternal, listener);
-        }
     }
 
     final Constants mConstants;
@@ -1074,7 +1037,7 @@
                         now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
 
                 if (sQuiescent) {
-                    sleepDisplayGroupNoUpdateLocked(DisplayGroup.DEFAULT, mClock.uptimeMillis(),
+                    goToSleepNoUpdateLocked(mClock.uptimeMillis(),
                             PowerManager.GO_TO_SLEEP_REASON_QUIESCENT,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
                 }
@@ -1092,8 +1055,8 @@
             mPolicy = getLocalService(WindowManagerPolicy.class);
             mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
             mAttentionDetector.systemReady(mContext);
-            mDisplayGroupPowerStateMapper = mInjector.createDisplayPowerRequestMapper(mLock,
-                    mDisplayManagerInternal, new DisplayGroupPowerChangeListener());
+            mDisplayPowerRequestMapper = new DisplayPowerRequestMapper(mContext.getSystemService(
+                    DisplayManager.class), mDisplayManagerInternal, mHandler);
 
             SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
 
@@ -1410,11 +1373,9 @@
                 opPackageName = wakeLock.mPackageName;
                 opUid = wakeLock.mOwnerUid;
             }
-            for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-                wakeDisplayGroupNoUpdateLocked(id, mClock.uptimeMillis(),
-                        PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag,
-                        opUid, opPackageName, opUid);
-            }
+            wakeUpNoUpdateLocked(mClock.uptimeMillis(),
+                    PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag,
+                    opUid, opPackageName, opUid);
         }
     }
 
@@ -1703,69 +1664,74 @@
         }
     }
 
-    private void wakeDisplayGroup(int groupId, long eventTime, @WakeReason int reason,
-            String details, int uid, String opPackageName, int opUid) {
+    private void wakeUpInternal(long eventTime, @WakeReason int reason, String details, int uid,
+            String opPackageName, int opUid) {
         synchronized (mLock) {
-            if (wakeDisplayGroupNoUpdateLocked(groupId, eventTime, reason, details, uid,
-                    opPackageName, opUid)) {
+            if (wakeUpNoUpdateLocked(eventTime, reason, details, uid, opPackageName, opUid)) {
                 updatePowerStateLocked();
             }
         }
     }
 
-    private boolean wakeDisplayGroupNoUpdateLocked(int groupId, long eventTime,
-            @WakeReason int reason, String details, int uid, String opPackageName, int opUid) {
+    private boolean wakeUpNoUpdateLocked(long eventTime, @WakeReason int reason, String details,
+            int reasonUid, String opPackageName, int opUid) {
         if (DEBUG_SPEW) {
-            Slog.d(TAG, "wakeDisplayGroupNoUpdateLocked: eventTime=" + eventTime
-                    +", groupId=" + groupId + ", uid=" + uid);
+            Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
         }
 
-        if (eventTime < mLastSleepTime || mForceSuspendActive || !mSystemReady) {
+        if (eventTime < mLastSleepTime || getWakefulnessLocked() == WAKEFULNESS_AWAKE
+                || mForceSuspendActive || !mSystemReady) {
             return false;
         }
 
-        final int currentState = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
-        if (currentState == WAKEFULNESS_AWAKE) {
-            return false;
-        }
+        Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
 
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay");
+        Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
         try {
-            Slog.i(TAG, "Powering on display group from"
-                    + PowerManagerInternal.wakefulnessToString(currentState)
-                    + " (groupId=" + groupId
-                    + ", uid=" + uid
+            Slog.i(TAG, "Waking up from "
+                    + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+                    + " (uid=" + reasonUid
                     + ", reason=" + PowerManager.wakeReasonToString(reason)
                     + ", details=" + details
                     + ")...");
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
 
-            setWakefulnessLocked(groupId, WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
-                    opPackageName, details);
-            mDisplayGroupPowerStateMapper.setLastPowerOnTimeLocked(groupId, eventTime);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
+            mLastWakeTime = eventTime;
+            mLastWakeReason = reason;
+            setWakefulnessLocked(WAKEFULNESS_AWAKE, reason, eventTime);
+
+            mNotifier.onWakeUp(reason, details, reasonUid, opPackageName, opUid);
+            userActivityNoUpdateLocked(
+                    eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
+
+            if (sQuiescent) {
+                mDirty |= DIRTY_QUIESCENT;
+            }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
-
         return true;
     }
 
-    private void sleepDisplayGroup(int groupId, long eventTime, int reason, int flags,
-            int uid) {
+    private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
         synchronized (mLock) {
-            if (sleepDisplayGroupNoUpdateLocked(groupId, eventTime, reason, flags, uid)) {
+            if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
                 updatePowerStateLocked();
             }
         }
     }
 
-    private boolean sleepDisplayGroupNoUpdateLocked(int groupId, long eventTime, int reason,
-            int flags, int uid) {
+    /**
+     * Puts the system in doze.
+     *
+     * This method is called goToSleep for historical reasons but actually attempts to DOZE,
+     * and only tucks itself in to SLEEP if requested with the flag
+     * {@link PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE}.
+     */
+    @SuppressWarnings("deprecation")
+    private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
         if (DEBUG_SPEW) {
-            Slog.d(TAG, "powerOffDisplayGroupNoUpdateLocked: eventTime=" + eventTime
-                    + ", groupId=" + groupId + ", reason=" + reason + ", flags=" + flags
-                    + ", uid=" + uid);
+            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
+                    + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);
         }
 
         if (eventTime < mLastWakeTime
@@ -1776,44 +1742,55 @@
             return false;
         }
 
-        final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
-        if (!PowerManagerInternal.isInteractive(wakefulness)) {
-            return false;
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay");
+        Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
         try {
             reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
                     Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
-            Slog.i(TAG, "Powering off display group due to "
-                    + PowerManager.sleepReasonToString(reason) + " (groupId= " + groupId
-                    + ", uid= " + uid + ")...");
+            Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
+                    + " (uid " + uid + ")...");
 
-            mDisplayGroupPowerStateMapper.setSandmanSummoned(groupId, true);
-            setWakefulnessLocked(groupId, WAKEFULNESS_DOZING, eventTime, uid, reason,
-                    /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
-            if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
-                reallySleepDisplayGroupNoUpdateLocked(groupId, eventTime, uid);
+            mLastSleepTime = eventTime;
+            mLastSleepReason = reason;
+            mSandmanSummoned = true;
+            mDozeStartInProgress = true;
+            setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
+
+            // Report the number of wake locks that will be cleared by going to sleep.
+            int numWakeLocksCleared = 0;
+            final int numWakeLocks = mWakeLocks.size();
+            for (int i = 0; i < numWakeLocks; i++) {
+                final WakeLock wakeLock = mWakeLocks.get(i);
+                switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+                    case PowerManager.FULL_WAKE_LOCK:
+                    case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+                    case PowerManager.SCREEN_DIM_WAKE_LOCK:
+                        numWakeLocksCleared += 1;
+                        break;
+                }
             }
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
+            EventLogTags.writePowerSleepRequested(numWakeLocksCleared);
+
+            // Skip dozing if requested.
+            if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
+                reallyGoToSleepNoUpdateLocked(eventTime, uid);
+            }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
         return true;
     }
 
-    private void dreamDisplayGroup(int groupId, long eventTime, int uid) {
+    private void napInternal(long eventTime, int uid) {
         synchronized (mLock) {
-            if (dreamDisplayGroupNoUpdateLocked(groupId, eventTime, uid)) {
+            if (napNoUpdateLocked(eventTime, uid)) {
                 updatePowerStateLocked();
             }
         }
     }
 
-    private boolean dreamDisplayGroupNoUpdateLocked(int groupId, long eventTime, int uid) {
+    private boolean napNoUpdateLocked(long eventTime, int uid) {
         if (DEBUG_SPEW) {
-            Slog.d(TAG, "dreamDisplayGroupNoUpdateLocked: eventTime=" + eventTime
-                    + ", uid=" + uid);
+            Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid);
         }
 
         if (eventTime < mLastWakeTime || getWakefulnessLocked() != WAKEFULNESS_AWAKE
@@ -1821,42 +1798,36 @@
             return false;
         }
 
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, "napDisplayGroup");
+        Trace.traceBegin(Trace.TRACE_TAG_POWER, "nap");
         try {
-            Slog.i(TAG, "Napping display group (groupId=" + groupId + ", uid=" + uid + ")...");
+            Slog.i(TAG, "Nap time (uid " + uid +")...");
 
-            mDisplayGroupPowerStateMapper.setSandmanSummoned(groupId, true);
-            setWakefulnessLocked(groupId, WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */
-                    0, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
-
+            mSandmanSummoned = true;
+            setWakefulnessLocked(WAKEFULNESS_DREAMING, 0, eventTime);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
         return true;
     }
 
-    private boolean reallySleepDisplayGroupNoUpdateLocked(int groupId, long eventTime, int uid) {
+    // Done dozing, drop everything and go to sleep.
+    private boolean reallyGoToSleepNoUpdateLocked(long eventTime, int uid) {
         if (DEBUG_SPEW) {
-            Slog.d(TAG, "reallySleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime
+            Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime
                     + ", uid=" + uid);
         }
 
         if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
-                || !mBootCompleted || !mSystemReady
-                || mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId)
-                == WAKEFULNESS_ASLEEP) {
+                || !mBootCompleted || !mSystemReady) {
             return false;
         }
 
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallySleepDisplayGroup");
+        Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallyGoToSleep");
         try {
-            Slog.i(TAG, "Sleeping display group (groupId=" + groupId + ", uid=" + uid +")...");
+            Slog.i(TAG, "Sleeping (uid " + uid +")...");
 
-            setWakefulnessLocked(groupId, WAKEFULNESS_ASLEEP, eventTime, uid,
-                    PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,  /* opUid= */ 0,
-                    /* opPackageName= */ null, /* details= */ null);
-            mDirty |= DIRTY_DISPLAY_GROUP_POWER_UPDATED;
+            setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+                    eventTime);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
@@ -1864,62 +1835,8 @@
     }
 
     @VisibleForTesting
-    void setWakefulnessLocked(int groupId, int wakefulness, long eventTime, int uid, int reason,
-            int opUid, String opPackageName, String details) {
-        if (mDisplayGroupPowerStateMapper.setWakefulnessLocked(groupId, wakefulness)) {
-            setGlobalWakefulnessLocked(mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked(),
-                    eventTime, reason, uid, opUid, opPackageName, details);
-        }
-    }
-
-    private void setGlobalWakefulnessLocked(int wakefulness, long eventTime, int reason, int uid,
-            int opUid, String opPackageName, String details) {
-        if (getWakefulnessLocked() == wakefulness) {
-            return;
-        }
-
-        // Phase 1: Handle pre-wakefulness change bookkeeping.
-        final String traceMethodName;
-        switch (wakefulness) {
-            case WAKEFULNESS_ASLEEP:
-                traceMethodName = "reallyGoToSleep";
-                Slog.i(TAG, "Sleeping (uid " + uid + ")...");
-                break;
-
-            case WAKEFULNESS_AWAKE:
-                traceMethodName = "wakeUp";
-                Slog.i(TAG, "Waking up from "
-                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
-                        + " (uid=" + uid
-                        + ", reason=" + PowerManager.wakeReasonToString(reason)
-                        + ", details=" + details
-                        + ")...");
-                mLastWakeTime = eventTime;
-                mLastWakeReason = reason;
-                break;
-
-            case WAKEFULNESS_DREAMING:
-                traceMethodName = "nap";
-                Slog.i(TAG, "Nap time (uid " + uid + ")...");
-                break;
-
-            case WAKEFULNESS_DOZING:
-                traceMethodName = "goToSleep";
-                Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
-                        + " (uid " + uid + ")...");
-
-                mLastSleepTime = eventTime;
-                mLastSleepReason = reason;
-                mDozeStartInProgress = true;
-                break;
-
-            default:
-                throw new IllegalArgumentException("Unexpected wakefulness: " + wakefulness);
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName);
-        try {
-            // Phase 2: Handle wakefulness change and bookkeeping.
+    void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
+        if (getWakefulnessLocked() != wakefulness) {
             // Under lock, invalidate before set ensures caches won't return stale values.
             mInjector.invalidateIsInteractiveCaches();
             mWakefulnessRaw = wakefulness;
@@ -1933,37 +1850,6 @@
                 mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
             }
             mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
-
-            // Phase 3: Handle post-wakefulness change bookkeeping.
-            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;
-                    }
-                    break;
-
-                case WAKEFULNESS_DOZING:
-                    // Report the number of wake locks that will be cleared by going to sleep.
-                    int numWakeLocksCleared = 0;
-                    final int numWakeLocks = mWakeLocks.size();
-                    for (int i = 0; i < numWakeLocks; i++) {
-                        final WakeLock wakeLock = mWakeLocks.get(i);
-                        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
-                            case PowerManager.FULL_WAKE_LOCK:
-                            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
-                            case PowerManager.SCREEN_DIM_WAKE_LOCK:
-                                numWakeLocksCleared += 1;
-                                break;
-                        }
-                    }
-                    EventLogTags.writePowerSleepRequested(numWakeLocksCleared);
-                    break;
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
     }
 
@@ -1986,7 +1872,7 @@
     }
 
     private void finishWakefulnessChangeIfNeededLocked() {
-        if (mWakefulnessChanging && mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()) {
+        if (mWakefulnessChanging && mDisplayReady) {
             if (getWakefulnessLocked() == WAKEFULNESS_DOZING
                     && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                 return; // wait until dream has enabled dozing
@@ -1998,6 +1884,13 @@
                     || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
                 logSleepTimeoutRecapturedLocked();
             }
+            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
+                final int latencyMs = (int) (mClock.uptimeMillis() - mLastWakeTime);
+                if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
+                    Slog.w(TAG, "Screen on took " + latencyMs + " ms");
+                }
+            }
             mWakefulnessChanging = false;
             mNotifier.onWakefulnessChangeFinished();
         }
@@ -2096,6 +1989,7 @@
         if ((dirty & DIRTY_BATTERY_STATE) != 0) {
             final boolean wasPowered = mIsPowered;
             final int oldPlugType = mPlugType;
+            final boolean oldLevelLow = mBatteryLevelLow;
             mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
             mPlugType = mBatteryManagerInternal.getPlugType();
             mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
@@ -2124,8 +2018,7 @@
                 final long now = mClock.uptimeMillis();
                 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
                         dockedOnWirelessCharger)) {
-                    wakeDisplayGroupNoUpdateLocked(DisplayGroup.DEFAULT, now,
-                            PowerManager.WAKE_REASON_PLUGGED_IN,
+                    wakeUpNoUpdateLocked(now, PowerManager.WAKE_REASON_PLUGGED_IN,
                             "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
                             mContext.getOpPackageName(), Process.SYSTEM_UID);
                 }
@@ -2407,8 +2300,7 @@
                     nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
                     if (now < nextTimeout) {
                         final DisplayPowerRequest displayPowerRequest =
-                                mDisplayGroupPowerStateMapper.getPowerRequestLocked(
-                                        DisplayGroup.DEFAULT);
+                                mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
                         if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
                                 || displayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
                             mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
@@ -2663,23 +2555,13 @@
                 }
                 final long time = mClock.uptimeMillis();
                 if (isAttentiveTimeoutExpired(time)) {
-                    // TODO (b/175764389): Support per-display timeouts.
-                    for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-                        changed = sleepDisplayGroupNoUpdateLocked(id, time,
-                                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
-                                PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
-                    }
+                    changed = goToSleepNoUpdateLocked(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()) {
-                        changed = dreamDisplayGroupNoUpdateLocked(id, time, Process.SYSTEM_UID);
-                    }
+                    changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
                 } else {
-                    // TODO (b/175764389): Support per-display timeouts.
-                    for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-                        changed = sleepDisplayGroupNoUpdateLocked(id, time,
-                                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
-                    }
+                    changed = goToSleepNoUpdateLocked(time,
+                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
                 }
             }
         }
@@ -2762,7 +2644,7 @@
                 | DIRTY_STAY_ON
                 | DIRTY_PROXIMITY_POSITIVE
                 | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
-            if (mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()) {
+            if (mDisplayReady) {
                 scheduleSandmanLocked();
             }
         }
@@ -2777,14 +2659,6 @@
         }
     }
 
-    private void handleSandman() {
-        for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-            if (mDisplayGroupPowerStateMapper.isSandmanSupported(id)) {
-                handleSandman(id);
-            }
-        }
-    }
-
     /**
      * Called when the device enters or exits a dreaming or dozing state.
      *
@@ -2792,18 +2666,16 @@
      * the dream and we don't want to hold our lock while doing so.  There is a risk that
      * the device will wake or go to sleep in the meantime so we have to handle that case.
      */
-    private void handleSandman(int groupId) { // runs on handler thread
+    private void handleSandman() { // runs on handler thread
         // Handle preconditions.
         final boolean startDreaming;
         final int wakefulness;
         synchronized (mLock) {
             mSandmanScheduled = false;
-            // TODO (b/175764708): Support per-display doze.
             wakefulness = getWakefulnessLocked();
-            if (mDisplayGroupPowerStateMapper.isSandmanSummoned(groupId)
-                    && mDisplayGroupPowerStateMapper.isReady(groupId)) {
-                startDreaming = canDreamLocked(groupId) || canDozeLocked();
-                mDisplayGroupPowerStateMapper.setSandmanSummoned(groupId, false);
+            if (mSandmanSummoned && mDisplayReady) {
+                startDreaming = canDreamLocked() || canDozeLocked();
+                mSandmanSummoned = false;
             } else {
                 startDreaming = false;
             }
@@ -2842,15 +2714,14 @@
 
             // If preconditions changed, wait for the next iteration to determine
             // whether the dream should continue (or be restarted).
-            if (mDisplayGroupPowerStateMapper.isSandmanSummoned(groupId)
-                    || mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId) != wakefulness) {
+            if (mSandmanSummoned || getWakefulnessLocked() != wakefulness) {
                 return; // wait for next cycle
             }
 
             // Determine whether the dream should continue.
             long now = mClock.uptimeMillis();
             if (wakefulness == WAKEFULNESS_DREAMING) {
-                if (isDreaming && canDreamLocked(groupId)) {
+                if (isDreaming && canDreamLocked()) {
                     if (mDreamsBatteryLevelDrainCutoffConfig >= 0
                             && mBatteryLevel < mBatteryLevelWhenDreamStarted
                                     - mDreamsBatteryLevelDrainCutoffConfig
@@ -2870,13 +2741,16 @@
 
                 // Dream has ended or will be stopped.  Update the power state.
                 if (isItBedTimeYetLocked()) {
-                    final int flags = isAttentiveTimeoutExpired(now)
-                            ? PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE : 0;
-                    sleepDisplayGroupNoUpdateLocked(groupId, now,
-                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags, Process.SYSTEM_UID);
+                    int flags = 0;
+                    if (isAttentiveTimeoutExpired(now)) {
+                        flags |= PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE;
+                    }
+                    goToSleepNoUpdateLocked(now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags,
+                            Process.SYSTEM_UID);
                     updatePowerStateLocked();
                 } else {
-                    wakeDisplayGroupNoUpdateLocked(groupId, now, PowerManager.WAKE_REASON_UNKNOWN,
+                    wakeUpNoUpdateLocked(now,
+                            PowerManager.WAKE_REASON_UNKNOWN,
                             "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
                             mContext.getOpPackageName(), Process.SYSTEM_UID);
                     updatePowerStateLocked();
@@ -2887,7 +2761,7 @@
                 }
 
                 // Doze has ended or will be stopped.  Update the power state.
-                reallySleepDisplayGroupNoUpdateLocked(groupId, now, Process.SYSTEM_UID);
+                reallyGoToSleepNoUpdateLocked(now, Process.SYSTEM_UID);
                 updatePowerStateLocked();
             }
         }
@@ -2899,11 +2773,11 @@
     }
 
     /**
-     * Returns true if the {@code groupId} is allowed to dream in its current state.
+     * Returns true if the device is allowed to dream in its current state.
      */
-    private boolean canDreamLocked(int groupId) {
+    private boolean canDreamLocked() {
         final DisplayPowerRequest displayPowerRequest =
-                mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId);
+                mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
         if (getWakefulnessLocked() != WAKEFULNESS_DREAMING
                 || !mDreamsSupportedConfig
                 || !mDreamsEnabledSetting
@@ -2941,113 +2815,91 @@
 
     /**
      * Updates the display power state asynchronously.
-     * When the update is finished, the ready state of the displays will be updated.  The display
-     * controllers post a message to tell us when the actual display power state
+     * When the update is finished, mDisplayReady will be set to true.  The display
+     * controller posts a message to tell us when the actual display power state
      * has been updated so we come back here to double-check and finish up.
      *
      * This function recalculates the display power state each time.
      *
-     * @return {@code true} if all displays became ready; {@code false} otherwise
+     * @return True if the display became ready.
      */
     private boolean updateDisplayPowerStateLocked(int dirty) {
-        final boolean oldDisplayReady = mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked();
+        final boolean oldDisplayReady = mDisplayReady;
         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)) != 0) {
             if ((dirty & DIRTY_QUIESCENT) != 0) {
                 sQuiescent = false;
             }
 
-            for (final int groupId : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-                final DisplayPowerRequest displayPowerRequest =
-                        mDisplayGroupPowerStateMapper.getPowerRequestLocked(groupId);
-                displayPowerRequest.policy = getDesiredScreenPolicyLocked(groupId);
+            final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+                    Display.DEFAULT_DISPLAY);
+            displayPowerRequest.policy = getDesiredScreenPolicyLocked();
 
-                // Determine appropriate screen brightness and auto-brightness adjustments.
-                final boolean autoBrightness;
-                final float screenBrightnessOverride;
-                if (!mBootCompleted) {
-                    // Keep the brightness steady during boot. This requires the
-                    // bootloader brightness and the default brightness to be identical.
-                    autoBrightness = false;
-                    screenBrightnessOverride = mScreenBrightnessDefault;
-                } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
-                    autoBrightness = false;
-                    screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
-                } else {
-                    autoBrightness = (mScreenBrightnessModeSetting ==
-                            Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-                    screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
-                }
-
-                // Update display power request.
-                displayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
-                displayPowerRequest.useAutoBrightness = autoBrightness;
-                displayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
-                displayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
-
-                updatePowerRequestFromBatterySaverPolicy(displayPowerRequest);
-
-                if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
-                    displayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
-                    if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0
-                            && !mDrawWakeLockOverrideFromSidekick) {
-                        if (displayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
-                            displayPowerRequest.dozeScreenState = Display.STATE_DOZE;
-                        }
-                        if (displayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
-                            displayPowerRequest.dozeScreenState = Display.STATE_ON;
-                        }
-                    }
-                    displayPowerRequest.dozeScreenBrightness =
-                            mDozeScreenBrightnessOverrideFromDreamManagerFloat;
-                } else {
-                    displayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
-                    displayPowerRequest.dozeScreenBrightness =
-                            PowerManager.BRIGHTNESS_INVALID_FLOAT;
-                }
-
-                final boolean ready = mDisplayManagerInternal.requestPowerState(groupId,
-                        displayPowerRequest, mRequestWaitForNegativeProximity);
-
-                if (DEBUG_SPEW) {
-                    Slog.d(TAG, "updateDisplayPowerStateLocked: displayReady=" + ready
-                            + ", groupId=" + groupId
-                            + ", policy=" + displayPowerRequest.policy
-                            + ", mWakefulness="
-                            + mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId)
-                            + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
-                            + ", mUserActivitySummary=0x" + Integer.toHexString(
-                            mUserActivitySummary)
-                            + ", mBootCompleted=" + mBootCompleted
-                            + ", screenBrightnessOverride="
-                            + displayPowerRequest.screenBrightnessOverride
-                            + ", useAutoBrightness=" + displayPowerRequest.useAutoBrightness
-                            + ", mScreenBrightnessBoostInProgress="
-                            + mScreenBrightnessBoostInProgress
-                            + ", mIsVrModeEnabled= " + mIsVrModeEnabled
-                            + ", sQuiescent=" + sQuiescent);
-                }
-
-                final boolean displayReadyStateChanged =
-                        mDisplayGroupPowerStateMapper.setDisplayGroupReadyLocked(groupId, ready);
-                if (ready && displayReadyStateChanged
-                        && mDisplayGroupPowerStateMapper.getWakefulnessLocked(
-                        groupId) == WAKEFULNESS_AWAKE) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
-                    final int latencyMs = (int) (mClock.uptimeMillis()
-                            - mDisplayGroupPowerStateMapper.getLastPowerOnTimeLocked(groupId));
-                    if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
-                        Slog.w(TAG, "Screen on took " + latencyMs + " ms");
-                    }
-                }
+            // Determine appropriate screen brightness and auto-brightness adjustments.
+            final boolean autoBrightness;
+            final float screenBrightnessOverride;
+            if (!mBootCompleted) {
+                // Keep the brightness steady during boot. This requires the
+                // bootloader brightness and the default brightness to be identical.
+                autoBrightness = false;
+                screenBrightnessOverride = mScreenBrightnessDefault;
+            } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
+                autoBrightness = false;
+                screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
+            } else {
+                autoBrightness = (mScreenBrightnessModeSetting ==
+                        Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+                screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
             }
 
+            // Update display power request.
+            displayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
+            displayPowerRequest.useAutoBrightness = autoBrightness;
+            displayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
+            displayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
+
+            updatePowerRequestFromBatterySaverPolicy(displayPowerRequest);
+
+            if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
+                displayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
+                if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0
+                        && !mDrawWakeLockOverrideFromSidekick) {
+                    if (displayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
+                        displayPowerRequest.dozeScreenState = Display.STATE_DOZE;
+                    }
+                    if (displayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
+                        displayPowerRequest.dozeScreenState = Display.STATE_ON;
+                    }
+                }
+                displayPowerRequest.dozeScreenBrightness =
+                        mDozeScreenBrightnessOverrideFromDreamManagerFloat;
+            } else {
+                displayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
+                displayPowerRequest.dozeScreenBrightness =
+                        PowerManager.BRIGHTNESS_INVALID_FLOAT;
+            }
+
+            mDisplayReady = mDisplayManagerInternal.requestPowerState(displayPowerRequest,
+                    mRequestWaitForNegativeProximity);
             mRequestWaitForNegativeProximity = false;
 
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
+                        + ", policy=" + displayPowerRequest.policy
+                        + ", mWakefulness=" + getWakefulnessLocked()
+                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+                        + ", mBootCompleted=" + mBootCompleted
+                        + ", screenBrightnessOverride=" + screenBrightnessOverride
+                        + ", useAutoBrightness=" + autoBrightness
+                        + ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress
+                        + ", mIsVrModeEnabled= " + mIsVrModeEnabled
+                        + ", sQuiescent=" + sQuiescent);
+            }
         }
-        return mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked() && !oldDisplayReady;
+        return mDisplayReady && !oldDisplayReady;
     }
 
     private void updateScreenBrightnessBoostLocked(int dirty) {
@@ -3081,11 +2933,12 @@
     }
 
     @VisibleForTesting
-    int getDesiredScreenPolicyLocked(int groupId) {
-        final int wakefulness = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
-        if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
+    int getDesiredScreenPolicyLocked() {
+        if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP || sQuiescent) {
             return DisplayPowerRequest.POLICY_OFF;
-        } else if (wakefulness == WAKEFULNESS_DOZING) {
+        }
+
+        if (getWakefulnessLocked() == WAKEFULNESS_DOZING) {
             if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
                 return DisplayPowerRequest.POLICY_DOZE;
             }
@@ -3115,6 +2968,7 @@
 
     private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
             new DisplayManagerInternal.DisplayPowerCallbacks() {
+        private int mDisplayState = Display.STATE_UNKNOWN;
 
         @Override
         public void onStateChanged() {
@@ -3145,25 +2999,29 @@
         }
 
         @Override
-        public void onDisplayStateChange(boolean allInactive, boolean allOff) {
+        public void onDisplayStateChange(int state) {
             // This method is only needed to support legacy display blanking behavior
             // where the display's power state is coupled to suspend or to the power HAL.
             // The order of operations matters here.
             synchronized (mLock) {
-                setPowerModeInternal(MODE_DISPLAY_INACTIVE, allInactive);
-                if (allOff) {
-                    if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
-                        setHalInteractiveModeLocked(false);
-                    }
-                    if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
-                        setHalAutoSuspendModeLocked(true);
-                    }
-                } else {
-                    if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
-                        setHalAutoSuspendModeLocked(false);
-                    }
-                    if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
-                        setHalInteractiveModeLocked(true);
+                if (mDisplayState != state) {
+                    mDisplayState = state;
+                    setPowerModeInternal(MODE_DISPLAY_INACTIVE,
+                            !Display.isActiveState(state));
+                    if (state == Display.STATE_OFF) {
+                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
+                            setHalInteractiveModeLocked(false);
+                        }
+                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+                            setHalAutoSuspendModeLocked(true);
+                        }
+                    } else {
+                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+                            setHalAutoSuspendModeLocked(false);
+                        }
+                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
+                            setHalInteractiveModeLocked(true);
+                        }
                     }
                 }
             }
@@ -3178,6 +3036,13 @@
         public void releaseSuspendBlocker() {
             mDisplaySuspendBlocker.release();
         }
+
+        @Override
+        public String toString() {
+            synchronized (this) {
+                return "state=" + Display.stateToString(mDisplayState);
+            }
+        }
     };
 
     private boolean shouldUseProximitySensorLocked() {
@@ -3193,13 +3058,9 @@
         final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
         final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
         final boolean autoSuspend = !needDisplaySuspendBlocker;
-        final DisplayPowerRequest displayPowerRequest =
-                mDisplayGroupPowerStateMapper.getPowerRequestLocked(DisplayGroup.DEFAULT);
-        final int[] groupIds = mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked();
-        boolean interactive = false;
-        for (int id : groupIds) {
-            interactive |= mDisplayGroupPowerStateMapper.getPowerRequestLocked(id).isBrightOrDim();
-        }
+        final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+                Display.DEFAULT_DISPLAY);
+        final boolean interactive = displayPowerRequest.isBrightOrDim();
 
         // Disable auto-suspend if needed.
         // FIXME We should consider just leaving auto-suspend enabled forever since
@@ -3229,7 +3090,7 @@
             // until the display is actually ready so that all transitions have
             // completed.  This is probably a good sign that things have gotten
             // too tangled over here...
-            if (interactive || mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()) {
+            if (interactive || mDisplayReady) {
                 setHalInteractiveModeLocked(interactive);
             }
         }
@@ -3255,10 +3116,29 @@
      * We do so if the screen is on or is in transition between states.
      */
     private boolean needDisplaySuspendBlockerLocked() {
-        if (!mDisplayGroupPowerStateMapper.areAllDisplaysReadyLocked()) {
+        if (!mDisplayReady) {
             return true;
         }
+        final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+                Display.DEFAULT_DISPLAY);
+        if (displayPowerRequest.isBrightOrDim()) {
+            // If we asked for the screen to be on but it is off due to the proximity
+            // sensor then we may suspend but only if the configuration allows it.
+            // On some hardware it may not be safe to suspend because the proximity
+            // sensor may not be correctly configured as a wake-up source.
+            if (!displayPowerRequest.useProximitySensor || !mProximityPositive
+                    || !mSuspendWhenScreenOffDueToProximityConfig) {
+                return true;
+            }
+        }
 
+        if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
+                && displayPowerRequest.dozeScreenState == Display.STATE_ON) {
+            // Although we are in DOZE and would normally allow the device to suspend,
+            // the doze service has explicitly requested the display to remain in the ON
+            // state which means we should hold the display suspend blocker.
+            return true;
+        }
         if (mScreenBrightnessBoostInProgress) {
             return true;
         }
@@ -3272,30 +3152,6 @@
             return true;
         }
 
-        final int[] groupIds = mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked();
-        for (int id : groupIds) {
-            final DisplayPowerRequest displayPowerRequest =
-                    mDisplayGroupPowerStateMapper.getPowerRequestLocked(id);
-            if (displayPowerRequest.isBrightOrDim()) {
-                // If we asked for the screen to be on but it is off due to the proximity
-                // sensor then we may suspend but only if the configuration allows it.
-                // On some hardware it may not be safe to suspend because the proximity
-                // sensor may not be correctly configured as a wake-up source.
-                if (!displayPowerRequest.useProximitySensor || !mProximityPositive
-                        || !mSuspendWhenScreenOffDueToProximityConfig) {
-                    return true;
-                }
-            }
-
-            if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
-                    && displayPowerRequest.dozeScreenState == Display.STATE_ON) {
-                // Although we are in DOZE and would normally allow the device to suspend,
-                // the doze service has explicitly requested the display to remain in the ON
-                // state which means we should hold the display suspend blocker.
-                return true;
-            }
-        }
-
         // Let the system suspend if the screen is off or dozing.
         return false;
     }
@@ -3829,15 +3685,9 @@
             synchronized (mLock) {
                 mForceSuspendActive = true;
                 // Place the system in an non-interactive state
-                boolean updatePowerState = false;
-                for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
-                    updatePowerState |= sleepDisplayGroupNoUpdateLocked(id, mClock.uptimeMillis(),
-                            PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND,
-                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid);
-                }
-                if (updatePowerState) {
-                    updatePowerStateLocked();
-                }
+                goToSleepInternal(mClock.uptimeMillis(),
+                        PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND,
+                        PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid);
 
                 // Disable all the partial wake locks as well
                 updateWakeLockDisabledStatesLocked();
@@ -3977,6 +3827,7 @@
             pw.println("  mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
             pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
             pw.println("  mSandmanScheduled=" + mSandmanScheduled);
+            pw.println("  mSandmanSummoned=" + mSandmanSummoned);
             pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
             pw.println("  mLightDeviceIdleMode=" + mLightDeviceIdleMode);
             pw.println("  mDeviceIdleMode=" + mDeviceIdleMode);
@@ -3994,6 +3845,7 @@
                     + TimeUtils.formatUptime(mLastScreenBrightnessBoostTime));
             pw.println("  mScreenBrightnessBoostInProgress="
                     + mScreenBrightnessBoostInProgress);
+            pw.println("  mDisplayReady=" + mDisplayReady);
             pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
             pw.println("  mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
 
@@ -4228,6 +4080,7 @@
                     PowerManagerServiceDumpProto.IS_REQUEST_WAIT_FOR_NEGATIVE_PROXIMITY,
                     mRequestWaitForNegativeProximity);
             proto.write(PowerManagerServiceDumpProto.IS_SANDMAN_SCHEDULED, mSandmanScheduled);
+            proto.write(PowerManagerServiceDumpProto.IS_SANDMAN_SUMMONED, mSandmanSummoned);
             proto.write(PowerManagerServiceDumpProto.IS_BATTERY_LEVEL_LOW, mBatteryLevelLow);
             proto.write(PowerManagerServiceDumpProto.IS_LIGHT_DEVICE_IDLE_MODE, mLightDeviceIdleMode);
             proto.write(PowerManagerServiceDumpProto.IS_DEVICE_IDLE_MODE, mDeviceIdleMode);
@@ -4254,6 +4107,7 @@
             proto.write(
                     PowerManagerServiceDumpProto.IS_SCREEN_BRIGHTNESS_BOOST_IN_PROGRESS,
                     mScreenBrightnessBoostInProgress);
+            proto.write(PowerManagerServiceDumpProto.IS_DISPLAY_READY, mDisplayReady);
             proto.write(
                     PowerManagerServiceDumpProto.IS_HOLDING_WAKE_LOCK_SUSPEND_BLOCKER,
                     mHoldingWakeLockSuspendBlocker);
@@ -5067,8 +4921,7 @@
             final int uid = Binder.getCallingUid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                wakeDisplayGroup(DisplayGroup.DEFAULT, eventTime, reason, details, uid,
-                        opPackageName, uid);
+                wakeUpInternal(eventTime, reason, details, uid, opPackageName, uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -5086,7 +4939,7 @@
             final int uid = Binder.getCallingUid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                sleepDisplayGroup(DisplayGroup.DEFAULT, eventTime, reason, flags, uid);
+                goToSleepInternal(eventTime, reason, flags, uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -5104,7 +4957,7 @@
             final int uid = Binder.getCallingUid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                dreamDisplayGroup(DisplayGroup.DEFAULT, eventTime, uid);
+                napInternal(eventTime, uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -5737,7 +5590,7 @@
             // also tells us that we're not already ignoring the proximity sensor.
 
             final DisplayPowerRequest displayPowerRequest =
-                    mDisplayGroupPowerStateMapper.getPowerRequestLocked(DisplayGroup.DEFAULT);
+                    mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
             if (displayPowerRequest.useProximitySensor && mProximityPositive) {
                 mDisplayManagerInternal.ignoreProximitySensorUntilChanged();
                 return true;
diff --git a/services/core/java/com/android/server/role/RoleManagerInternal.java b/services/core/java/com/android/server/role/RoleManagerLocal.java
similarity index 77%
rename from services/core/java/com/android/server/role/RoleManagerInternal.java
rename to services/core/java/com/android/server/role/RoleManagerLocal.java
index 7598bf7..f11d99d 100644
--- a/services/core/java/com/android/server/role/RoleManagerInternal.java
+++ b/services/core/java/com/android/server/role/RoleManagerLocal.java
@@ -18,14 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
-import android.util.ArrayMap;
-import android.util.ArraySet;
+
+import java.util.Map;
+import java.util.Set;
 
 /**
- * Internal calls into {@link RoleManagerService}.
+ * Internal calls into {@link RoleService}.
+ *
+ * @hide
  */
-public abstract class RoleManagerInternal {
-
+//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public interface RoleManagerLocal {
     /**
      * Get all roles and their holders.
      *
@@ -34,6 +37,5 @@
      * @return The roles and their holders
      */
     @NonNull
-    public abstract ArrayMap<String, ArraySet<String>> getRolesAndHolders(
-            @UserIdInt int userId);
+    Map<String, Set<String>> getRolesAndHolders(@UserIdInt int userId);
 }
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleService.java
similarity index 79%
rename from services/core/java/com/android/server/role/RoleManagerService.java
rename to services/core/java/com/android/server/role/RoleService.java
index bc5ddd3..944ebf0 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleService.java
@@ -33,8 +33,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.Signature;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.ParcelFileDescriptor;
@@ -45,37 +43,33 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
-import android.util.PackageUtils;
-import android.util.Slog;
+import android.util.Log;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.infra.ThrottledRunnable;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.dump.DualDumpOutputStream;
-import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.server.FgThread;
-import com.android.server.LocalServices;
+import com.android.server.LocalManagerRegistry;
 import com.android.server.SystemService;
-import com.android.server.pm.UserManagerInternal;
+import com.android.server.role.compat.UserHandleCompat;
+import com.android.server.role.util.ArrayUtils;
+import com.android.server.role.util.CollectionUtils;
+import com.android.server.role.util.ForegroundThread;
 
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -85,8 +79,8 @@
  *
  * @see RoleManager
  */
-public class RoleManagerService extends SystemService implements RoleUserState.Callback {
-    private static final String LOG_TAG = RoleManagerService.class.getSimpleName();
+public class RoleService extends SystemService implements RoleUserState.Callback {
+    private static final String LOG_TAG = RoleService.class.getSimpleName();
 
     private static final boolean DEBUG = false;
 
@@ -95,15 +89,13 @@
     @NonNull
     private final AppOpsManager mAppOpsManager;
     @NonNull
-    private final PackageManagerInternal mPackageManagerInternal;
-    @NonNull
-    private final UserManagerInternal mUserManagerInternal;
+    private final UserManager mUserManager;
 
     @NonNull
     private final Object mLock = new Object();
 
     @NonNull
-    private final LegacyRoleStateProvider mLegacyRoleStateProvider;
+    private final RoleServicePlatformHelper mPlatformHelper;
 
     /**
      * Maps user id to its state.
@@ -128,7 +120,7 @@
             new SparseArray<>();
 
     @NonNull
-    private final Handler mListenerHandler = FgThread.getHandler();
+    private final Handler mListenerHandler = ForegroundThread.getHandler();
 
     /**
      * Maps user id to its throttled runnable for granting default roles.
@@ -138,19 +130,17 @@
     private final SparseArray<ThrottledRunnable> mGrantDefaultRolesThrottledRunnables =
             new SparseArray<>();
 
-    public RoleManagerService(@NonNull Context context,
-            @NonNull LegacyRoleStateProvider legacyRoleStateProvider) {
+    public RoleService(@NonNull Context context) {
         super(context);
 
-        mLegacyRoleStateProvider = legacyRoleStateProvider;
+        mPlatformHelper = LocalManagerRegistry.getManager(RoleServicePlatformHelper.class);
 
         RoleControllerManager.initializeRemoteServiceComponentName(context);
 
         mAppOpsManager = context.getSystemService(AppOpsManager.class);
-        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
-        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        mUserManager = context.getSystemService(UserManager.class);
 
-        LocalServices.addService(RoleManagerInternal.class, new Internal());
+        LocalManagerRegistry.addManager(RoleManagerLocal.class, new Local());
 
         registerUserRemovedReceiver();
     }
@@ -183,9 +173,9 @@
         getContext().registerReceiverForAllUsers(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1));
+                int userId = UserHandleCompat.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1));
                 if (DEBUG) {
-                    Slog.i(LOG_TAG, "Packages changed - re-running initial grants for user "
+                    Log.i(LOG_TAG, "Packages changed - re-running initial grants for user "
                             + userId);
                 }
                 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
@@ -209,7 +199,7 @@
         try {
             future.get(30, TimeUnit.SECONDS);
         } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            Slog.e(LOG_TAG, "Failed to grant default roles for user " + userId, e);
+            Log.e(LOG_TAG, "Failed to grant default roles for user " + userId, e);
         }
     }
 
@@ -218,7 +208,7 @@
         synchronized (mLock) {
             runnable = mGrantDefaultRolesThrottledRunnables.get(userId);
             if (runnable == null) {
-                runnable = new ThrottledRunnable(FgThread.getHandler(),
+                runnable = new ThrottledRunnable(ForegroundThread.getHandler(),
                         GRANT_DEFAULT_ROLES_INTERVAL_MILLIS,
                         () -> maybeGrantDefaultRolesInternal(userId));
                 mGrantDefaultRolesThrottledRunnables.put(userId, runnable);
@@ -232,19 +222,19 @@
     private AndroidFuture<Void> maybeGrantDefaultRolesInternal(@UserIdInt int userId) {
         RoleUserState userState = getOrCreateUserState(userId);
         String oldPackagesHash = userState.getPackagesHash();
-        String newPackagesHash = computePackageStateHash(userId);
+        String newPackagesHash = mPlatformHelper.computePackageStateHash(userId);
         if (Objects.equals(oldPackagesHash, newPackagesHash)) {
             if (DEBUG) {
-                Slog.i(LOG_TAG, "Already granted default roles for packages hash "
+                Log.i(LOG_TAG, "Already granted default roles for packages hash "
                         + newPackagesHash);
             }
             return AndroidFuture.completedFuture(null);
         }
 
         // Some package state has changed, so grant default roles again.
-        Slog.i(LOG_TAG, "Granting default roles...");
+        Log.i(LOG_TAG, "Granting default roles...");
         AndroidFuture<Void> future = new AndroidFuture<>();
-        getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(),
+        getOrCreateController(userId).grantDefaultRoles(ForegroundThread.getExecutor(),
                 successful -> {
                     if (successful) {
                         userState.setPackagesHash(newPackagesHash);
@@ -256,51 +246,12 @@
         return future;
     }
 
-    @Nullable
-    private String computePackageStateHash(@UserIdInt int userId) {
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
-
-        mPackageManagerInternal.forEachInstalledPackage(pkg -> {
-            try {
-                dataOutputStream.writeUTF(pkg.getPackageName());
-                dataOutputStream.writeLong(pkg.getLongVersionCode());
-                dataOutputStream.writeInt(mPackageManagerInternal.getApplicationEnabledState(
-                        pkg.getPackageName(), userId));
-
-                ArraySet<String> enabledComponents =
-                        mPackageManagerInternal.getEnabledComponents(pkg.getPackageName(), userId);
-                int numComponents = CollectionUtils.size(enabledComponents);
-                dataOutputStream.writeInt(numComponents);
-                for (int i = 0; i < numComponents; i++) {
-                    dataOutputStream.writeUTF(enabledComponents.valueAt(i));
-                }
-
-                ArraySet<String> disabledComponents =
-                        mPackageManagerInternal.getDisabledComponents(pkg.getPackageName(), userId);
-                numComponents = CollectionUtils.size(disabledComponents);
-                for (int i = 0; i < numComponents; i++) {
-                    dataOutputStream.writeUTF(disabledComponents.valueAt(i));
-                }
-
-                for (Signature signature : pkg.getSigningDetails().signatures) {
-                    dataOutputStream.write(signature.toByteArray());
-                }
-            } catch (IOException e) {
-                // Never happens for ByteArrayOutputStream and DataOutputStream.
-                throw new AssertionError(e);
-            }
-        }, userId);
-
-        return PackageUtils.computeSha256Digest(byteArrayOutputStream.toByteArray());
-    }
-
     @NonNull
     private RoleUserState getOrCreateUserState(@UserIdInt int userId) {
         synchronized (mLock) {
             RoleUserState userState = mUserStates.get(userId);
             if (userState == null) {
-                userState = new RoleUserState(userId, mLegacyRoleStateProvider, this);
+                userState = new RoleUserState(userId, mPlatformHelper, this);
                 mUserStates.put(userId, userState);
             }
             return userState;
@@ -321,7 +272,7 @@
                     throw new RuntimeException(e);
                 }
                 controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName(
-                        FgThread.getHandler(), context);
+                        ForegroundThread.getHandler(), context);
                 mControllers.put(userId, controller);
             }
             return controller;
@@ -369,8 +320,7 @@
 
     @Override
     public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
-        mListenerHandler.sendMessage(PooledLambda.obtainMessage(
-                RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId));
+        mListenerHandler.post(() -> notifyRoleHoldersChanged(roleName, userId));
     }
 
     @WorkerThread
@@ -381,7 +331,7 @@
         }
 
         RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners(
-                UserHandle.USER_ALL);
+                UserHandleCompat.USER_ALL);
         if (allUsersListeners != null) {
             notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId);
         }
@@ -398,7 +348,7 @@
                 try {
                     listener.onRoleHoldersChanged(roleName, userId);
                 } catch (RemoteException e) {
-                    Slog.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e);
+                    Log.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e);
                 }
             }
         } finally {
@@ -412,7 +362,7 @@
         public boolean isRoleAvailable(@NonNull String roleName) {
             Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
 
-            int userId = UserHandle.getUserId(getCallingUid());
+            int userId = UserHandleCompat.getUserId(getCallingUid());
             return getOrCreateUserState(userId).isRoleAvailable(roleName);
         }
 
@@ -424,7 +374,7 @@
             Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
             Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
 
-            int userId = UserHandle.getUserId(callingUid);
+            int userId = UserHandleCompat.getUserId(callingUid);
             ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
             if (roleHolders == null) {
                 return false;
@@ -435,8 +385,8 @@
         @NonNull
         @Override
         public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) {
-            if (!mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (!isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return Collections.emptyList();
             }
             enforceCrossUserPermission(userId, false, "getRoleHoldersAsUser");
@@ -456,8 +406,8 @@
         public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
                 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
                 @NonNull RemoteCallback callback) {
-            if (!mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (!isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return;
             }
             enforceCrossUserPermission(userId, false, "addRoleHolderAsUser");
@@ -476,8 +426,8 @@
         public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
                 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
                 @NonNull RemoteCallback callback) {
-            if (!mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (!isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return;
             }
             enforceCrossUserPermission(userId, false, "removeRoleHolderAsUser");
@@ -496,8 +446,8 @@
         public void clearRoleHoldersAsUser(@NonNull String roleName,
                 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
                 @NonNull RemoteCallback callback) {
-            if (!mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (!isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return;
             }
             enforceCrossUserPermission(userId, false, "clearRoleHoldersAsUser");
@@ -513,8 +463,8 @@
         @Override
         public void addOnRoleHoldersChangedListenerAsUser(
                 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
-            if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return;
             }
             enforceCrossUserPermission(userId, true, "addOnRoleHoldersChangedListenerAsUser");
@@ -531,8 +481,8 @@
         @Override
         public void removeOnRoleHoldersChangedListenerAsUser(
                 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
-            if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
-                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+            if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) {
+                Log.e(LOG_TAG, "user " + userId + " does not exist");
                 return;
             }
             enforceCrossUserPermission(userId, true, "removeOnRoleHoldersChangedListenerAsUser");
@@ -556,7 +506,7 @@
 
             Objects.requireNonNull(roleNames, "roleNames cannot be null");
 
-            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
             getOrCreateUserState(userId).setRoleNames(roleNames);
         }
 
@@ -570,7 +520,7 @@
             Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
             Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
 
-            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
             return getOrCreateUserState(userId).addRoleHolder(roleName, packageName);
         }
 
@@ -584,7 +534,7 @@
             Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
             Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
 
-            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
             return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName);
         }
 
@@ -596,24 +546,30 @@
 
             Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
 
-            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
             return getOrCreateUserState(userId).getHeldRoles(packageName);
         }
 
+        private boolean isUserExistent(@UserIdInt int userId) {
+            // FIXME: This checks whether the user is alive, but we should check for whether the
+            //  user is existent.
+            return mUserManager.getUserHandles(true).contains(UserHandle.of(userId));
+        }
+
         private void enforceCrossUserPermission(@UserIdInt int userId, boolean allowAll,
                 @NonNull String message) {
             final int callingUid = Binder.getCallingUid();
-            final int callingUserId = UserHandle.getUserId(callingUid);
+            final int callingUserId = UserHandleCompat.getUserId(callingUid);
             if (userId == callingUserId) {
                 return;
             }
-            Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
-                    || (allowAll && userId == UserHandle.USER_ALL), "Invalid user " + userId);
+            Preconditions.checkArgument(userId >= UserHandleCompat.USER_SYSTEM
+                    || (allowAll && userId == UserHandleCompat.USER_ALL), "Invalid user " + userId);
             getContext().enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
-            if (callingUid == Process.SHELL_UID && userId >= UserHandle.USER_SYSTEM) {
-                if (mUserManagerInternal.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
-                        userId)) {
+            if (callingUid == Process.SHELL_UID && userId >= UserHandleCompat.USER_SYSTEM) {
+                if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_DEBUGGING_FEATURES,
+                        UserHandle.of(userId))) {
                     throw new SecurityException("Shell does not have permission to access user "
                             + userId);
                 }
@@ -624,7 +580,7 @@
         public int handleShellCommand(@NonNull ParcelFileDescriptor in,
                 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
                 @NonNull String[] args) {
-            return new RoleManagerShellCommand(this).exec(this, in.getFileDescriptor(),
+            return new RoleShellCommand(this).exec(this, in.getFileDescriptor(),
                     out.getFileDescriptor(), err.getFileDescriptor(), args);
         }
 
@@ -632,7 +588,7 @@
         @Override
         public String getBrowserRoleHolder(@UserIdInt int userId) {
             final int callingUid = Binder.getCallingUid();
-            if (UserHandle.getUserId(callingUid) != userId) {
+            if (UserHandleCompat.getUserId(callingUid) != userId) {
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
             }
@@ -673,12 +629,12 @@
             final Context context = getContext();
             context.enforceCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-            if (UserHandle.getUserId(Binder.getCallingUid()) != userId) {
+            if (UserHandleCompat.getUserId(Binder.getCallingUid()) != userId) {
                 context.enforceCallingOrSelfPermission(
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
             }
 
-            if (!mUserManagerInternal.exists(userId)) {
+            if (!isUserExistent(userId)) {
                 return false;
             }
 
@@ -701,7 +657,7 @@
                 try {
                     future.get(5, TimeUnit.SECONDS);
                 } catch (InterruptedException | ExecutionException | TimeoutException e) {
-                    Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
+                    Log.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
                     return false;
                 }
             } finally {
@@ -735,7 +691,7 @@
                 dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream(
                         new FileOutputStream(fd)));
             } else {
-                fout.println("ROLE MANAGER STATE (dumpsys role):");
+                fout.println("ROLE STATE (dumpsys role):");
                 dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, "  "));
             }
 
@@ -766,11 +722,14 @@
         }
     }
 
-    private class Internal extends RoleManagerInternal {
+    private class Local implements RoleManagerLocal {
         @NonNull
         @Override
-        public ArrayMap<String, ArraySet<String>> getRolesAndHolders(@UserIdInt int userId) {
-            return getOrCreateUserState(userId).getRolesAndHolders();
+        public Map<String, Set<String>> getRolesAndHolders(@UserIdInt int userId) {
+            // Convert ArrayMap<String, ArraySet<String>> to Map<String, Set<String>> for the API.
+            //noinspection unchecked
+            return (Map<String, Set<String>>) (Map<String, ?>)
+                    getOrCreateUserState(userId).getRolesAndHolders();
         }
     }
 }
diff --git a/services/core/java/com/android/server/role/LegacyRoleStateProvider.java b/services/core/java/com/android/server/role/RoleServicePlatformHelper.java
similarity index 68%
rename from services/core/java/com/android/server/role/LegacyRoleStateProvider.java
rename to services/core/java/com/android/server/role/RoleServicePlatformHelper.java
index ec4cfc1..d804d13 100644
--- a/services/core/java/com/android/server/role/LegacyRoleStateProvider.java
+++ b/services/core/java/com/android/server/role/RoleServicePlatformHelper.java
@@ -23,21 +23,30 @@
 import java.util.Set;
 
 /**
- * Provider for legacy role state.
- * <p>
- * The role state may come from two sources, either the different pre-role default app settings, or
- * the pre-modularization roles.xml file stored in platform.
+ * Helper inside the platform for role service.
  *
  * @hide
  */
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-public interface LegacyRoleStateProvider {
+public interface RoleServicePlatformHelper {
     /**
      * Get the legacy role state stored in the platform.
+     * <p>
+     * The role state may come from two sources, either the different pre-role default app settings,
+     * or the pre-modularization roles.xml file stored in platform.
      *
      * @param userId the user ID
      * @return a mapping of role name to its set of holders
      */
     @NonNull
     Map<String, Set<String>> getLegacyRoleState(@UserIdInt int userId);
+
+    /**
+     * Compute a hash for the current package state in the system.
+     *
+     * @param userId the user ID
+     * @return the computed hash
+     */
+    @NonNull
+    String computePackageStateHash(@UserIdInt int userId);
 }
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleShellCommand.java
similarity index 94%
rename from services/core/java/com/android/server/role/RoleManagerShellCommand.java
rename to services/core/java/com/android/server/role/RoleShellCommand.java
index 96f3c29..6e0d81a 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleShellCommand.java
@@ -21,19 +21,19 @@
 import android.app.role.IRoleManager;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
-import android.os.UserHandle;
 
 import com.android.modules.utils.BasicShellCommandHandler;
+import com.android.server.role.compat.UserHandleCompat;
 
 import java.io.PrintWriter;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
-class RoleManagerShellCommand extends BasicShellCommandHandler {
+class RoleShellCommand extends BasicShellCommandHandler {
     @NonNull
     private final IRoleManager mRoleManager;
 
-    RoleManagerShellCommand(@NonNull IRoleManager roleManager) {
+    RoleShellCommand(@NonNull IRoleManager roleManager) {
         mRoleManager = roleManager;
     }
 
@@ -86,7 +86,7 @@
     }
 
     private int getUserIdMaybe() {
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandleCompat.USER_SYSTEM;
         String option = getNextOption();
         if (option != null && option.equals("--user")) {
             userId = Integer.parseInt(getNextArgRequired());
@@ -139,7 +139,7 @@
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
-        pw.println("Role manager (role) commands:");
+        pw.println("Role (role) commands:");
         pw.println("  help or -h");
         pw.println("    Print this help text.");
         pw.println();
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index f5a79ea..52861c5 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -25,15 +25,14 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.dump.DualDumpOutputStream;
-import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.role.persistence.RolesPersistence;
 import com.android.role.persistence.RolesState;
+import com.android.server.role.util.BackgroundThread;
+import com.android.server.role.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -57,7 +56,7 @@
     private final int mUserId;
 
     @NonNull
-    private final LegacyRoleStateProvider mLegacyStateProvider;
+    private final RoleServicePlatformHelper mPlatformHelper;
 
     @NonNull
     private final Callback mCallback;
@@ -92,13 +91,13 @@
      * Create a new user state, and read its state from disk if previously persisted.
      *
      * @param userId the user id for this user state
-     * @param legacyStateProvider the provider for legacy role state
+     * @param platformHelper the platform helper
      * @param callback the callback for this user state
      */
-    public RoleUserState(@UserIdInt int userId,
-            @NonNull LegacyRoleStateProvider legacyStateProvider, @NonNull Callback callback) {
+    public RoleUserState(@UserIdInt int userId, @NonNull RoleServicePlatformHelper platformHelper,
+            @NonNull Callback callback) {
         mUserId = userId;
-        mLegacyStateProvider = legacyStateProvider;
+        mPlatformHelper = platformHelper;
         mCallback = callback;
 
         readFile();
@@ -197,7 +196,7 @@
         synchronized (mLock) {
             if (!mRoles.containsKey(roleName)) {
                 mRoles.put(roleName, new ArraySet<>());
-                Slog.i(LOG_TAG, "Added new role: " + roleName);
+                Log.i(LOG_TAG, "Added new role: " + roleName);
                 scheduleWriteFileLocked();
                 return true;
             } else {
@@ -221,7 +220,7 @@
                 if (!roleNames.contains(roleName)) {
                     ArraySet<String> packageNames = mRoles.valueAt(i);
                     if (!packageNames.isEmpty()) {
-                        Slog.e(LOG_TAG, "Holders of a removed role should have been cleaned up,"
+                        Log.e(LOG_TAG, "Holders of a removed role should have been cleaned up,"
                                 + " role: " + roleName + ", holders: " + packageNames);
                     }
                     mRoles.removeAt(i);
@@ -255,7 +254,7 @@
         synchronized (mLock) {
             ArraySet<String> roleHolders = mRoles.get(roleName);
             if (roleHolders == null) {
-                Slog.e(LOG_TAG, "Cannot add role holder for unknown role, role: " + roleName
+                Log.e(LOG_TAG, "Cannot add role holder for unknown role, role: " + roleName
                         + ", package: " + packageName);
                 return false;
             }
@@ -286,7 +285,7 @@
         synchronized (mLock) {
             ArraySet<String> roleHolders = mRoles.get(roleName);
             if (roleHolders == null) {
-                Slog.e(LOG_TAG, "Cannot remove role holder for unknown role, role: " + roleName
+                Log.e(LOG_TAG, "Cannot remove role holder for unknown role, role: " + roleName
                         + ", package: " + packageName);
                 return false;
             }
@@ -330,8 +329,7 @@
         }
 
         if (!mWriteScheduled) {
-            mWriteHandler.sendMessageDelayed(PooledLambda.obtainMessage(RoleUserState::writeFile,
-                    this), WRITE_DELAY_MILLIS);
+            mWriteHandler.postDelayed(this::writeFile, WRITE_DELAY_MILLIS);
             mWriteScheduled = true;
         }
     }
@@ -363,7 +361,7 @@
                 mPackagesHash = roleState.getPackagesHash();
                 roles = roleState.getRoles();
             } else {
-                roles = mLegacyStateProvider.getLegacyRoleState(mUserId);
+                roles = mPlatformHelper.getLegacyRoleState(mUserId);
             }
             mRoles.clear();
             for (Map.Entry<String, Set<String>> entry : roles.entrySet()) {
diff --git a/services/core/java/com/android/server/role/compat/UserHandleCompat.java b/services/core/java/com/android/server/role/compat/UserHandleCompat.java
new file mode 100644
index 0000000..8f14c1f
--- /dev/null
+++ b/services/core/java/com/android/server/role/compat/UserHandleCompat.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.server.role.compat;
+
+import android.annotation.UserIdInt;
+import android.os.UserHandle;
+
+/**
+ * Helper for accessing features in {@link UserHandle}.
+ */
+public final class UserHandleCompat {
+    /**
+     * A user ID to indicate all users on the device.
+     */
+    public static final int USER_ALL = UserHandle.ALL.getIdentifier();
+
+    /**
+     * A user ID to indicate the "system" user of the device.
+     */
+    public static final int USER_SYSTEM = UserHandle.SYSTEM.getIdentifier();
+
+    private UserHandleCompat() {}
+
+    /**
+     * Get the user ID of a given UID.
+     *
+     * @param uid the UID
+     * @return the user ID
+     */
+    @UserIdInt
+    public static int getUserId(int uid) {
+        return UserHandle.getUserHandleForUid(uid).getIdentifier();
+    }
+}
diff --git a/services/core/java/com/android/server/role/util/ArrayUtils.java b/services/core/java/com/android/server/role/util/ArrayUtils.java
new file mode 100644
index 0000000..8b7c07b
--- /dev/null
+++ b/services/core/java/com/android/server/role/util/ArrayUtils.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.role.util;
+
+import android.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Array utilities.
+ */
+public final class ArrayUtils {
+    private ArrayUtils() {}
+
+    /**
+     * @see java.util.List#contains(Object)
+     */
+    public static <T> boolean contains(@Nullable T[] array, T value) {
+        return indexOf(array, value) != -1;
+    }
+
+    /**
+     * Get the first element of an array, or {@code null} if none.
+     *
+     * @param array the array
+     * @param <T> the type of the elements of the array
+     * @return first element of an array, or {@code null} if none
+     */
+    public static <T> T firstOrNull(@Nullable T[] array) {
+        return !isEmpty(array) ? array[0] : null;
+    }
+
+    /**
+     * @see java.util.List#indexOf(Object)
+     */
+    public static <T> int indexOf(@Nullable T[] array, T value) {
+        if (array == null) {
+            return -1;
+        }
+        final int length = array.length;
+        for (int i = 0; i < length; i++) {
+            final T element = array[i];
+            if (Objects.equals(element, value)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * @see java.util.List#isEmpty()
+     */
+    public static <T> boolean isEmpty(@Nullable T[] array) {
+        return array == null || array.length == 0;
+    }
+}
diff --git a/services/core/java/com/android/server/role/util/BackgroundThread.java b/services/core/java/com/android/server/role/util/BackgroundThread.java
new file mode 100644
index 0000000..385595b
--- /dev/null
+++ b/services/core/java/com/android/server/role/util/BackgroundThread.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 com.android.server.role.util;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Shared singleton background thread.
+ */
+public class BackgroundThread extends HandlerThread {
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static BackgroundThread sInstance;
+    @GuardedBy("sLock")
+    private static Handler sHandler;
+    @GuardedBy("sLock")
+    private static Executor sExecutor;
+
+    private BackgroundThread() {
+        super(BackgroundThread.class.getName());
+    }
+
+    @GuardedBy("sLock")
+    private static void ensureInstanceLocked() {
+        if (sInstance == null) {
+            sInstance = new BackgroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sExecutor = new HandlerExecutor(sHandler);
+        }
+    }
+
+    /**
+     * Get the singleton instance of thi class.
+     *
+     * @return the singleton instance of thi class
+     */
+    @NonNull
+    public static BackgroundThread get() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sInstance;
+        }
+    }
+
+    /**
+     * Get the {@link Handler} for this thread.
+     *
+     * @return the {@link Handler} for this thread.
+     */
+    @NonNull
+    public static Handler getHandler() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sHandler;
+        }
+    }
+
+    /**
+     * Get the {@link Executor} for this thread.
+     *
+     * @return the {@link Executor} for this thread.
+     */
+    @NonNull
+    public static Executor getExecutor() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sExecutor;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/role/util/CollectionUtils.java b/services/core/java/com/android/server/role/util/CollectionUtils.java
new file mode 100644
index 0000000..f924fbc
--- /dev/null
+++ b/services/core/java/com/android/server/role/util/CollectionUtils.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.role.util;
+
+import android.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * {@link Collection} utilities.
+ */
+public class CollectionUtils {
+    private CollectionUtils() {}
+
+    /**
+     * Get the first element of a {@link List}, or {@code null} if none.
+     *
+     * @param list the {@link List}, or {@code null}
+     * @param <E> the element type of the {@link List}
+     * @return the first element of the {@link List}, or {@code 0} if none
+     */
+    @Nullable
+    public static <E> E firstOrNull(@Nullable List<E> list) {
+        return !isEmpty(list) ? list.get(0) : null;
+    }
+
+    /**
+     * Check whether a {@link Collection} is empty or {@code null}.
+     *
+     * @param collection the {@link Collection}, or {@code null}
+     * @return whether the {@link Collection} is empty or {@code null}
+     */
+    public static boolean isEmpty(@Nullable Collection<?> collection) {
+        return collection == null || collection.isEmpty();
+    }
+
+    /**
+     * Get the size of a {@link Collection}, or {@code 0} if {@code null}.
+     *
+     * @param collection the {@link Collection}, or {@code null}
+     * @return the size of the {@link Collection}, or {@code 0} if {@code null}
+     */
+    public static int size(@Nullable Collection<?> collection) {
+        return collection != null ? collection.size() : 0;
+    }
+
+    /**
+     * Get the size of a {@link Map}, or {@code 0} if {@code null}.
+     *
+     * @param collection the {@link Map}, or {@code null}
+     * @return the size of the {@link Map}, or {@code 0} if {@code null}
+     */
+    public static int size(@Nullable Map<?, ?> collection) {
+        return collection != null ? collection.size() : 0;
+    }
+}
diff --git a/services/core/java/com/android/server/role/util/ForegroundThread.java b/services/core/java/com/android/server/role/util/ForegroundThread.java
new file mode 100644
index 0000000..05da59e
--- /dev/null
+++ b/services/core/java/com/android/server/role/util/ForegroundThread.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 com.android.server.role.util;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Shared singleton foreground thread.
+ */
+public class ForegroundThread extends HandlerThread {
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static ForegroundThread sInstance;
+    @GuardedBy("sLock")
+    private static Handler sHandler;
+    @GuardedBy("sLock")
+    private static Executor sExecutor;
+
+    private ForegroundThread() {
+        super(ForegroundThread.class.getName());
+    }
+
+    @GuardedBy("sLock")
+    private static void ensureInstanceLocked() {
+        if (sInstance == null) {
+            sInstance = new ForegroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sExecutor = new HandlerExecutor(sHandler);
+        }
+    }
+
+    /**
+     * Get the singleton instance of thi class.
+     *
+     * @return the singleton instance of thi class
+     */
+    @NonNull
+    public static ForegroundThread get() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sInstance;
+        }
+    }
+
+    /**
+     * Get the {@link Handler} for this thread.
+     *
+     * @return the {@link Handler} for this thread.
+     */
+    @NonNull
+    public static Handler getHandler() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sHandler;
+        }
+    }
+
+    /**
+     * Get the {@link Executor} for this thread.
+     *
+     * @return the {@link Executor} for this thread.
+     */
+    @NonNull
+    public static Executor getExecutor() {
+        synchronized (sLock) {
+            ensureInstanceLocked();
+            return sExecutor;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 225bd82..6ec71b7 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -60,8 +60,7 @@
     private final IBinder mService = new IFileIntegrityService.Stub() {
         @Override
         public boolean isApkVeritySupported() {
-            return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
-                    || SystemProperties.getInt("ro.apk_verity.mode", 0) == 2;
+            return FileIntegrityService.isApkVeritySupported();
         }
 
         @Override
@@ -111,6 +110,11 @@
         }
     };
 
+    public static boolean isApkVeritySupported() {
+        return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
+                || SystemProperties.getInt("ro.apk_verity.mode", 0) == 2;
+    }
+
     public FileIntegrityService(final Context context) {
         super(context);
         try {
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
new file mode 100644
index 0000000..91b240b
--- /dev/null
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 36824
+
+per-file FileIntegrityService.java = victorhsieh@google.com
+per-file VerityUtils.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/services/core/java/com/android/server/security/VerityUtils.java
index f204aa2..09ee001 100644
--- a/services/core/java/com/android/server/security/VerityUtils.java
+++ b/services/core/java/com/android/server/security/VerityUtils.java
@@ -73,7 +73,12 @@
         if (Files.size(Paths.get(signaturePath)) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
             throw new SecurityException("Signature file is unexpectedly large: " + signaturePath);
         }
-        byte[] pkcs7Signature = Files.readAllBytes(Paths.get(signaturePath));
+        setUpFsverity(filePath, Files.readAllBytes(Paths.get(signaturePath)));
+    }
+
+    /** Enables fs-verity for the file with a PKCS#7 detached signature bytes. */
+    public static void setUpFsverity(@NonNull String filePath, @NonNull byte[] pkcs7Signature)
+            throws IOException {
         // This will fail if the public key is not already in .fs-verity kernel keyring.
         int errno = enableFsverityNative(filePath, pkcs7Signature);
         if (errno != 0) {
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
index eced894..90ac69a 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
@@ -42,7 +42,7 @@
     static final String TAG = "SoundTriggerHw2Enforcer";
 
     final ISoundTriggerHw2 mUnderlying;
-    Map<Integer, Boolean> mModelStates = new HashMap<>();
+    final Map<Integer, Boolean> mModelStates = new HashMap<>();
 
     public SoundTriggerHw2Enforcer(
             ISoundTriggerHw2 underlying) {
@@ -62,12 +62,12 @@
     public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, Callback callback,
             int cookie) {
         try {
-            int handle = mUnderlying.loadSoundModel(soundModel, new CallbackEnforcer(callback),
-                    cookie);
             synchronized (mModelStates) {
+                int handle = mUnderlying.loadSoundModel(soundModel, new CallbackEnforcer(callback),
+                        cookie);
                 mModelStates.put(handle, false);
+                return handle;
             }
-            return handle;
         } catch (RuntimeException e) {
             throw handleException(e);
         }
@@ -77,13 +77,13 @@
     public int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel, Callback callback,
             int cookie) {
         try {
-            int handle = mUnderlying.loadPhraseSoundModel(soundModel,
-                    new CallbackEnforcer(callback),
-                    cookie);
             synchronized (mModelStates) {
+                int handle = mUnderlying.loadPhraseSoundModel(soundModel,
+                        new CallbackEnforcer(callback),
+                        cookie);
                 mModelStates.put(handle, false);
+                return handle;
             }
-            return handle;
         } catch (RuntimeException e) {
             throw handleException(e);
         }
@@ -92,8 +92,8 @@
     @Override
     public void unloadSoundModel(int modelHandle) {
         try {
-            mUnderlying.unloadSoundModel(modelHandle);
             synchronized (mModelStates) {
+                mUnderlying.unloadSoundModel(modelHandle);
                 mModelStates.remove(modelHandle);
             }
         } catch (RuntimeException e) {
@@ -104,8 +104,8 @@
     @Override
     public void stopRecognition(int modelHandle) {
         try {
-            mUnderlying.stopRecognition(modelHandle);
             synchronized (mModelStates) {
+                mUnderlying.stopRecognition(modelHandle);
                 mModelStates.replace(modelHandle, false);
             }
         } catch (RuntimeException e) {
@@ -116,8 +116,8 @@
     @Override
     public void stopAllRecognitions() {
         try {
-            mUnderlying.stopAllRecognitions();
             synchronized (mModelStates) {
+                mUnderlying.stopAllRecognitions();
                 for (Map.Entry<Integer, Boolean> entry : mModelStates.entrySet()) {
                     entry.setValue(false);
                 }
@@ -131,9 +131,9 @@
     public void startRecognition(int modelHandle, RecognitionConfig config, Callback callback,
             int cookie) {
         try {
-            mUnderlying.startRecognition(modelHandle, config, new CallbackEnforcer(callback),
-                    cookie);
             synchronized (mModelStates) {
+                mUnderlying.startRecognition(modelHandle, config, new CallbackEnforcer(callback),
+                        cookie);
                 mModelStates.replace(modelHandle, true);
             }
         } catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index e7cda02..14855ae 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -156,12 +156,13 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.BatteryService;
 import com.android.server.BinderCallsStatsService;
+import com.android.server.LocalManagerRegistry;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.am.MemoryStatUtil.MemoryStat;
 import com.android.server.notification.NotificationManagerService;
-import com.android.server.role.RoleManagerInternal;
+import com.android.server.role.RoleManagerLocal;
 import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
 import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
 import com.android.server.stats.pull.netstats.NetworkStatsExt;
@@ -2916,7 +2917,8 @@
         final long callingToken = Binder.clearCallingIdentity();
         try {
             PackageManager pm = mContext.getPackageManager();
-            RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
+            RoleManagerLocal roleManagerLocal = LocalManagerRegistry.getManager(
+                    RoleManagerLocal.class);
 
             List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
 
@@ -2924,27 +2926,23 @@
             for (int userNum = 0; userNum < numUsers; userNum++) {
                 int userId = users.get(userNum).getUserHandle().getIdentifier();
 
-                ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
+                Map<String, Set<String>> roles = roleManagerLocal.getRolesAndHolders(userId);
 
-                int numRoles = roles.size();
-                for (int roleNum = 0; roleNum < numRoles; roleNum++) {
-                    String roleName = roles.keyAt(roleNum);
-                    ArraySet<String> holders = roles.valueAt(roleNum);
+                for (Map.Entry<String, Set<String>> roleEntry : roles.entrySet()) {
+                    String roleName = roleEntry.getKey();
+                    Set<String> packageNames = roleEntry.getValue();
 
-                    int numHolders = holders.size();
-                    for (int holderNum = 0; holderNum < numHolders; holderNum++) {
-                        String holderName = holders.valueAt(holderNum);
-
+                    for (String packageName : packageNames) {
                         PackageInfo pkg;
                         try {
-                            pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
+                            pkg = pm.getPackageInfoAsUser(packageName, 0, userId);
                         } catch (PackageManager.NameNotFoundException e) {
-                            Slog.w(TAG, "Role holder " + holderName + " not found");
+                            Slog.w(TAG, "Role holder " + packageName + " not found");
                             return StatsManager.PULL_SKIP;
                         }
 
                         pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                                atomTag, pkg.applicationInfo.uid, holderName, roleName));
+                                atomTag, pkg.applicationInfo.uid, packageName, roleName));
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 6306c5c..d664651a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.statusbar;
 
 import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
+import static android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.Manifest;
@@ -613,6 +614,14 @@
         }
     };
 
+    /**
+     * Returns true if the target disable flag (target2) is set
+     */
+    private boolean isDisable2FlagSet(int target2) {
+        final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
+        return ((disabled2 & target2) == target2);
+    }
+
     // ================================================================================
     // From IStatusBarService
     // ================================================================================
@@ -620,6 +629,10 @@
     public void expandNotificationsPanel() {
         enforceExpandStatusBar();
 
+        if (isDisable2FlagSet(DISABLE2_NOTIFICATION_SHADE)) {
+            return;
+        }
+
         if (mBar != null) {
             try {
                 mBar.animateExpandNotificationsPanel();
@@ -658,6 +671,10 @@
     public void togglePanel() {
         enforceExpandStatusBar();
 
+        if (isDisable2FlagSet(DISABLE2_NOTIFICATION_SHADE)) {
+            return;
+        }
+
         if (mBar != null) {
             try {
                 mBar.togglePanel();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index ba0292df..aa41d2a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -225,6 +225,7 @@
 import android.app.PictureInPictureParams;
 import android.app.ResultInfo;
 import android.app.WaitResult;
+import android.app.WindowConfiguration;
 import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.app.servertransaction.ActivityLifecycleItem;
 import android.app.servertransaction.ActivityRelaunchItem;
@@ -2255,11 +2256,17 @@
                 || info.supportsPictureInPicture();
     }
 
-    /** @return whether this activity is non-resizeable or forced to be resizeable */
-    boolean isNonResizableOrForcedResizable(int windowingMode) {
+    /** @return whether this activity is non-resizeable but is forced to be resizable. */
+    boolean canForceResizeNonResizable(int windowingMode) {
         if (windowingMode == WINDOWING_MODE_PINNED && info.supportsPictureInPicture()) {
             return false;
         }
+        if (WindowConfiguration.inMultiWindowMode(windowingMode)
+                && mAtmService.mSupportsNonResizableMultiWindow
+                && !mAtmService.mForceResizableActivities) {
+            // The non resizable app will be letterboxed instead of being forced resizable.
+            return false;
+        }
         return info.resizeMode != RESIZE_MODE_RESIZEABLE
                 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
     }
@@ -2289,16 +2296,19 @@
      *         stack.
      */
     boolean supportsFreeform() {
-        return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
+        return mAtmService.mSupportsFreeformWindowManagement
+                // Either the activity is resizable, or we allow size compat in freeform.
+                && (supportsResizeableMultiWindow() || mAtmService.mSizeCompatFreeform);
     }
 
     /**
      * @return whether this activity supports non-PiP multi-window.
      */
-    private boolean supportsResizeableMultiWindow() {
+    boolean supportsResizeableMultiWindow() {
         return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
                 && (ActivityInfo.isResizeableMode(info.resizeMode)
-                        || mAtmService.mForceResizableActivities);
+                    || mAtmService.mForceResizableActivities
+                    || mAtmService.mSupportsNonResizableMultiWindow);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index efae16b..03982e3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -56,6 +56,7 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
@@ -568,6 +569,7 @@
     boolean mSupportsMultiDisplay;
     boolean mForceResizableActivities;
     boolean mSizeCompatFreeform;
+    boolean mSupportsNonResizableMultiWindow;
 
     final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
 
@@ -785,6 +787,8 @@
                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
         final boolean sizeCompatFreeform = Settings.Global.getInt(
                 resolver, DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM, 0) != 0;
+        final boolean supportsNonResizableMultiWindow = Settings.Global.getInt(
+                resolver, DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0) != 0;
 
         // Transfer any global setting for forcing RTL layout, into a System Property
         DisplayProperties.debug_force_rtl(forceRtl);
@@ -799,6 +803,7 @@
         synchronized (mGlobalLock) {
             mForceResizableActivities = forceResizable;
             mSizeCompatFreeform = sizeCompatFreeform;
+            mSupportsNonResizableMultiWindow = supportsNonResizableMultiWindow;
             final boolean multiWindowFormEnabled = freeformWindowManagement
                     || supportsSplitScreenMultiWindow
                     || supportsPictureInPicture
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index d2ce369..e7a77b81 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1704,6 +1704,12 @@
                     + " task=" + task);
         }
 
+        // It is ok to move the task to multi window only if the task supports multi window.
+        if (inMultiWindowMode && !stack.inPinnedWindowingMode()
+                && task.supportsNonPipMultiWindow()) {
+            return stack;
+        }
+
         // Leave the task in its current stack or a fullscreen stack if it isn't resizeable and the
         // preferred stack is in multi-window mode.
         if (inMultiWindowMode && !task.isResizeable()) {
@@ -2226,7 +2232,7 @@
     private void handleForcedResizableTaskIfNeeded(Task task, int reason) {
         final ActivityRecord topActivity = task.getTopNonFinishingActivity();
         if (topActivity == null || topActivity.noDisplay
-                || !topActivity.isNonResizableOrForcedResizable(task.getWindowingMode())) {
+                || !topActivity.canForceResizeNonResizable(task.getWindowingMode())) {
             return;
         }
         mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 00b6ceb..fa86a11 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -1084,6 +1084,7 @@
                         .setPosition(taskSurface, mFinishBounds.left, mFinishBounds.top)
                         .setWindowCrop(taskSurface, mFinishBounds.width(), mFinishBounds.height())
                         .apply();
+                mTask.mLastRecentsAnimationBounds.set(mFinishBounds);
                 mFinishBounds.setEmpty();
             } else if (!mTask.isAttached()) {
                 // Apply the task's pending transaction in case it is detached and its transaction
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4300aed..149e977 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2104,30 +2104,6 @@
                 onTop);
     }
 
-    boolean moveTopRootTaskActivityToPinnedRootTask(int rootTaskId) {
-        final Task rootTask = getRootTask(rootTaskId);
-        if (rootTask == null) {
-            throw new IllegalArgumentException(
-                    "moveTopStackActivityToPinnedRootTask: Unknown rootTaskId=" + rootTaskId);
-        }
-
-        final ActivityRecord r = rootTask.topRunningActivity();
-        if (r == null) {
-            Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: No top running activity"
-                    + " in rootTask=" + rootTask);
-            return false;
-        }
-
-        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
-            Slog.w(TAG, "moveTopStackActivityToPinnedRootTask: Picture-In-Picture not supported "
-                    + "for r=" + r);
-            return false;
-        }
-
-        moveActivityToPinnedRootTask(r, "moveTopStackActivityToPinnedRootTask");
-        return true;
-    }
-
     void moveActivityToPinnedRootTask(ActivityRecord r, String reason) {
         mService.deferWindowLayout();
 
@@ -2153,13 +2129,16 @@
                 rootTask = task;
             } else {
                 // In the case of multiple activities, we will create a new task for it and then
-                // move the PIP activity into the task.
+                // move the PIP activity into the task. Note that we explicitly defer the task
+                // appear being sent in this case and mark this newly created task to been visible.
                 rootTask = new Task.Builder(mService)
                         .setActivityType(r.getActivityType())
                         .setOnTop(true)
                         .setActivityInfo(r.info)
                         .setParent(taskDisplayArea)
                         .setIntent(r.intent)
+                        .setDeferTaskAppear(true)
+                        .setHasBeenVisible(true)
                         .build();
                 // It's possible the task entering PIP is in freeform, so save the last
                 // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore
@@ -2167,12 +2146,19 @@
                 rootTask.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
                 rootTask.setBounds(task.getBounds());
 
+                // Move reparent bounds from original task to the new one.
+                rootTask.mLastRecentsAnimationBounds.set(task.mLastRecentsAnimationBounds);
+                task.mLastRecentsAnimationBounds.setEmpty();
+
                 // There are multiple activities in the task and moving the top activity should
                 // reveal/leave the other activities in their original task.
                 // On the other hand, ActivityRecord#onParentChanged takes care of setting the
                 // up-to-dated pinned stack information on this newly created stack.
                 r.reparent(rootTask, MAX_VALUE, reason);
 
+                // Ensure the leash of new task is in sync with its current bounds after reparent.
+                rootTask.maybeApplyLastRecentsAnimationBounds();
+
                 // In the case of this activity entering PIP due to it being moved to the back,
                 // the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be
                 // ran. But, since its visibility did not change (note how it was STOPPED/not
@@ -2201,6 +2187,7 @@
             // TODO(task-org): Figure-out more structured way to do this long term.
             r.setWindowingMode(intermediateWindowingMode);
             rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
+            rootTask.setDeferTaskAppear(false);
 
             // Reset the state that indicates it can enter PiP while pausing after we've moved it
             // to the pinned stack
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index fb50fa1e..defe494 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -463,6 +463,15 @@
     int mMinWidth;
     int mMinHeight;
 
+    // The bounds of the target when recents animation is finished.
+    // This is originally introduced to carry out the current surface control position and window
+    // crop when a multi-activity task enters pip with autoEnterPip enabled. In such case,
+    // the surface control of the task will be animated in Launcher and then the top activity is
+    // reparented to pinned root task.
+    // Do not forget to reset this to null after reparenting.
+    // TODO: remove this once the recents animation is moved to the Shell
+    final Rect mLastRecentsAnimationBounds = new Rect();
+
     static final int LAYER_RANK_INVISIBLE = -1;
     // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
     // This number will be assigned when we evaluate OOM scores for all visible tasks.
@@ -1963,7 +1972,20 @@
                 && mAtmService.mSupportsSplitScreenMultiWindow
                 && (mAtmService.mForceResizableActivities
                         || (isResizeable(false /* checkSupportsPip */)
-                                && !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
+                                && !ActivityInfo.isPreserveOrientationMode(mResizeMode))
+                        || mAtmService.mSupportsNonResizableMultiWindow);
+    }
+
+    boolean supportsFreeform() {
+        return mAtmService.mSupportsFreeformWindowManagement
+                && (isResizeable(false /* checkSupportsPip */)
+                        || mAtmService.mSupportsNonResizableMultiWindow);
+    }
+
+    boolean supportsNonPipMultiWindow() {
+        return mAtmService.mSupportsMultiWindow
+                && (isResizeable(false /* checkSupportsPip */)
+                    || mAtmService.mSupportsNonResizableMultiWindow);
     }
 
     /**
@@ -2809,14 +2831,15 @@
         }
 
         // Do not allow non-resizable tasks to be in a multi-window mode, unless it is in pinned
-        // windowing mode or is in size compat freeform mode
+        // windowing mode or supports non-resizable tasks in multi-window mode.
         if (!isResizeable()) {
             final int candidateWindowingMode =
                     windowingMode != WINDOWING_MODE_UNDEFINED ? windowingMode : parentWindowingMode;
             if (WindowConfiguration.inMultiWindowMode(candidateWindowingMode)
                     && candidateWindowingMode != WINDOWING_MODE_PINNED
                     && (candidateWindowingMode != WINDOWING_MODE_FREEFORM
-                            || !mTaskSupervisor.mService.mSizeCompatFreeform)) {
+                            || !mTaskSupervisor.mService.mSizeCompatFreeform)
+                    && !mTaskSupervisor.mService.mSupportsNonResizableMultiWindow) {
                 getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(
                         WINDOWING_MODE_FULLSCREEN);
             }
@@ -4158,9 +4181,9 @@
 
     private @Nullable PictureInPictureParams getPictureInPictureParams(Task top) {
         if (top == null) return null;
-        final ActivityRecord rootActivity = top.getRootActivity();
-        return (rootActivity == null || rootActivity.pictureInPictureArgs.empty())
-                ? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs);
+        final ActivityRecord topVisibleActivity = top.getTopVisibleActivity();
+        return (topVisibleActivity == null || topVisibleActivity.pictureInPictureArgs.empty())
+                ? null : new PictureInPictureParams(topVisibleActivity.pictureInPictureArgs);
     }
 
     /**
@@ -4984,7 +5007,7 @@
                 commitPendingTransaction();
             }
 
-            sendTaskAppeared();
+            if (!mDeferTaskAppear) sendTaskAppeared();
             if (!isRootTask()) {
                 getRootTask().setHasBeenVisible(true);
             }
@@ -5352,7 +5375,7 @@
         }
         if (likelyResolvedMode != WINDOWING_MODE_FULLSCREEN
                 && topActivity != null && !topActivity.noDisplay
-                && topActivity.isNonResizableOrForcedResizable(likelyResolvedMode)) {
+                && topActivity.canForceResizeNonResizable(likelyResolvedMode)) {
             // Inform the user that they are starting an app that may not work correctly in
             // multi-window mode.
             final String packageName = topActivity.info.applicationInfo.packageName;
@@ -7589,6 +7612,17 @@
         reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM);
     }
 
+    void maybeApplyLastRecentsAnimationBounds() {
+        if (!mLastRecentsAnimationBounds.isEmpty()) {
+            getPendingTransaction()
+                    .setPosition(mSurfaceControl, mLastRecentsAnimationBounds.left,
+                            mLastRecentsAnimationBounds.top)
+                    .setWindowCrop(mSurfaceControl, mLastRecentsAnimationBounds.width(),
+                            mLastRecentsAnimationBounds.height());
+            mLastRecentsAnimationBounds.setEmpty();
+        }
+    }
+
     private void updateSurfaceBounds() {
         updateSurfaceSize(getSyncTransaction());
         updateSurfacePositionNonOrganized();
@@ -7824,6 +7858,7 @@
         private boolean mDeferTaskAppear;
         private IBinder mLaunchCookie;
         private boolean mOnTop;
+        private boolean mHasBeenVisible;
 
         Builder(ActivityTaskManagerService atm) {
             mAtmService = atm;
@@ -7921,6 +7956,11 @@
             return this;
         }
 
+        Builder setHasBeenVisible(boolean hasBeenVisible) {
+            mHasBeenVisible = hasBeenVisible;
+            return this;
+        }
+
         private Builder setUserId(int userId) {
             mUserId = userId;
             return this;
@@ -8114,6 +8154,7 @@
             }
 
             final Task task = buildInner();
+            task.mHasBeenVisible = mHasBeenVisible;
 
             // Set activity type before adding the root task to TaskDisplayArea, so home task can
             // be cached, see TaskDisplayArea#addRootTaskReferenceIfNeeded().
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index a83f81d..407ed6c 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -48,7 +48,6 @@
 import android.util.IntArray;
 import android.util.Slog;
 import android.view.SurfaceControl;
-import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -1485,14 +1484,18 @@
         boolean supportsPip = mAtmService.mSupportsPictureInPicture;
         if (supportsMultiWindow) {
             if (task != null) {
-                supportsMultiWindow = task.isResizeable();
                 supportsSplitScreen = task.supportsSplitScreenWindowingMode();
-                // TODO: Do we need to check for freeform and Pip support here?
+                supportsFreeform = task.supportsFreeform();
+                supportsMultiWindow = task.supportsNonPipMultiWindow()
+                        // When the activity needs to be moved to PIP while the Task is not in PIP,
+                        // it can be moved to a new created PIP Task, so WINDOWING_MODE_PINNED is
+                        // always valid for Task as long as the device supports it.
+                        || (windowingMode == WINDOWING_MODE_PINNED && supportsPip);
             } else if (r != null) {
-                supportsMultiWindow = r.isResizeable();
                 supportsSplitScreen = r.supportsSplitScreenWindowingMode();
                 supportsFreeform = r.supportsFreeform();
                 supportsPip = r.supportsPictureInPicture();
+                supportsMultiWindow = r.supportsResizeableMultiWindow() || supportsPip;
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ad88469..ab2c2915 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -40,6 +40,7 @@
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
@@ -795,6 +796,8 @@
                 DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
         private final Uri mSizeCompatFreeformUri = Settings.Global.getUriFor(
                 DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM);
+        private final Uri mSupportsNonResizableMultiWindowUri = Settings.Global.getUriFor(
+                DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW);
         private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
                 DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
         private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
@@ -821,6 +824,8 @@
             resolver.registerContentObserver(mForceResizableUri, false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(mSizeCompatFreeformUri, false, this,
                     UserHandle.USER_ALL);
+            resolver.registerContentObserver(mSupportsNonResizableMultiWindowUri, false, this,
+                    UserHandle.USER_ALL);
             resolver.registerContentObserver(mRenderShadowsInCompositorUri, false, this,
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(mDisplaySettingsPathUri, false, this,
@@ -863,6 +868,11 @@
                 return;
             }
 
+            if (mSupportsNonResizableMultiWindowUri.equals(uri)) {
+                updateSupportsNonResizableMultiWindow();
+                return;
+            }
+
             if (mRenderShadowsInCompositorUri.equals(uri)) {
                 setShadowRenderer();
                 return;
@@ -963,6 +973,14 @@
             mAtmService.mSizeCompatFreeform = sizeCompatFreeform;
         }
 
+        void updateSupportsNonResizableMultiWindow() {
+            ContentResolver resolver = mContext.getContentResolver();
+            final boolean supportsNonResizableMultiWindow = Settings.Global.getInt(resolver,
+                    DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0) != 0;
+
+            mAtmService.mSupportsNonResizableMultiWindow = supportsNonResizableMultiWindow;
+        }
+
         void updateDisplaySettingsLocation() {
             final ContentResolver resolver = mContext.getContentResolver();
             final String filePath = Settings.Global.getString(resolver,
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index dcab478..bf8253d 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -490,15 +490,23 @@
                     return 0;
                 }
                 if (task.getParent() != newParent) {
-                    if (newParent instanceof TaskDisplayArea) {
+                    if (newParent.asTaskDisplayArea() != null) {
                         // For now, reparenting to displayarea is different from other reparents...
-                        as.reparent((TaskDisplayArea) newParent, hop.getToTop());
-                    } else if (newParent.inMultiWindowMode() && !task.isResizeable()
-                            && task.isLeafTask()) {
-                        Slog.w(TAG, "Can't support task that doesn't support multi-window mode in"
-                                + " multi-window mode... newParent=" + newParent + " task=" + task);
-                        return 0;
+                        as.reparent(newParent.asTaskDisplayArea(), hop.getToTop());
                     } else {
+                        if (newParent.inMultiWindowMode() && task.isLeafTask()) {
+                            if (newParent.inPinnedWindowingMode()) {
+                                Slog.w(TAG, "Can't support moving a task to another PIP window..."
+                                        + " newParent=" + newParent + " task=" + task);
+                                return 0;
+                            }
+                            if (!task.supportsNonPipMultiWindow()) {
+                                Slog.w(TAG, "Can't support task that doesn't support multi-window"
+                                        + " mode in multi-window mode... newParent=" + newParent
+                                        + " task=" + task);
+                                return 0;
+                            }
+                        }
                         task.reparent((Task) newParent,
                                 hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
                                 false /*moveParents*/, "sanitizeAndApplyHierarchyOp");
@@ -550,6 +558,11 @@
                     + newParent + " hop=" + hop);
             return 0;
         }
+        if (newParent.inPinnedWindowingMode()) {
+            Slog.e(TAG, "reparentChildrenTasksHierarchyOp newParent in PIP="
+                    + newParent + " hop=" + hop);
+            return 0;
+        }
 
         final boolean newParentInMultiWindow = newParent.inMultiWindowMode();
         final WindowContainer finalCurrentParent = currentParent;
@@ -567,11 +580,11 @@
                 // are reparenting from.
                 return;
             }
-
-            if (newParentInMultiWindow && !task.isResizeable()) {
-                Slog.e(TAG, "reparentChildrenTasksHierarchyOp non-resizeable task=" + task);
+            if (newParentInMultiWindow && !task.supportsNonPipMultiWindow()) {
+                Slog.e(TAG, "reparentChildrenTasksHierarchyOp non-resizeable task to multi window,"
+                        + " task=" + task);
+                return;
             }
-
             if (!ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())) return;
             if (!ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) return;
 
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 0d37f60..5676909 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -519,13 +519,21 @@
         }
     }
 
-    public boolean areBackgroundActivityStartsAllowed() {
+    /**
+     * Is this WindowProcessController in the state of allowing background FGS start?
+     */
+    public boolean areBackgroundFgsStartsAllowed() {
         synchronized (mAtm.mGlobalLock) {
-            return areBackgroundActivityStartsAllowed(mAtm.getBalAppSwitchesAllowed());
+            return areBackgroundActivityStartsAllowed(mAtm.getBalAppSwitchesAllowed(), true);
         }
     }
 
     boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) {
+        return areBackgroundActivityStartsAllowed(appSwitchAllowed, false);
+    }
+
+    boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed,
+            boolean isCheckingForFgsStart) {
         // If app switching is not allowed, we ignore all the start activity grace period
         // exception so apps cannot start itself in onPause() after pressing home button.
         if (appSwitchAllowed) {
@@ -579,7 +587,7 @@
             return true;
         }
         // allow if the flag was explicitly set
-        if (isBackgroundStartAllowedByToken()) {
+        if (isBackgroundStartAllowedByToken(isCheckingForFgsStart)) {
             if (DEBUG_ACTIVITY_STARTS) {
                 Slog.d(TAG, "[WindowProcessController(" + mPid
                         + ")] Activity start allowed: process allowed by token");
@@ -590,13 +598,20 @@
     }
 
     /**
-     * If there are no tokens, we don't allow *by token*. If there are tokens, we ask the callback
-     * if the start is allowed for these tokens, otherwise if there is no callback we allow.
+     * If there are no tokens, we don't allow *by token*. If there are tokens and
+     * isCheckingForFgsStart is false, we ask the callback if the start is allowed for these tokens,
+     * otherwise if there is no callback we allow.
      */
-    private boolean isBackgroundStartAllowedByToken() {
+    private boolean isBackgroundStartAllowedByToken(boolean isCheckingForFgsStart) {
         if (mBackgroundActivityStartTokens.isEmpty()) {
             return false;
         }
+
+        if (isCheckingForFgsStart) {
+            /// The checking is for BG-FGS-start.
+            return true;
+        }
+
         if (mBackgroundActivityStartCallback == null) {
             // We have tokens but no callback to decide => allow
             return true;
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 13078b6..9d013c1 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -140,7 +140,6 @@
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@2.1",
-        "android.hardware.gnss@3.0",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
         "android.hardware.graphics.bufferqueue@1.0",
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index b2d6b15..a87b513 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -22,14 +22,12 @@
 #include <android/hardware/gnss/1.1/IGnss.h>
 #include <android/hardware/gnss/2.0/IGnss.h>
 #include <android/hardware/gnss/2.1/IGnss.h>
-#include <android/hardware/gnss/3.0/IGnss.h>
 
 #include <android/hardware/gnss/1.0/IGnssMeasurement.h>
 #include <android/hardware/gnss/1.1/IGnssMeasurement.h>
 #include <android/hardware/gnss/2.0/IGnssMeasurement.h>
 #include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
 #include <android/hardware/gnss/2.1/IGnssMeasurement.h>
-#include <android/hardware/gnss/3.0/IGnssPsds.h>
 #include <android/hardware/gnss/BnGnss.h>
 #include <android/hardware/gnss/BnGnssCallback.h>
 #include <android/hardware/gnss/BnGnssMeasurementCallback.h>
@@ -167,9 +165,8 @@
 using android::hardware::gnss::V1_0::IGnssNi;
 using android::hardware::gnss::V1_0::IGnssNiCallback;
 using android::hardware::gnss::V1_0::IGnssXtra;
+using android::hardware::gnss::V1_0::IGnssXtraCallback;
 using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
-using android::hardware::gnss::V3_0::IGnssPsds;
-using android::hardware::gnss::V3_0::IGnssPsdsCallback;
 
 using MeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
 using MeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
@@ -190,7 +187,6 @@
 using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
 using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
 using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
-using IGnss_V3_0 = android::hardware::gnss::V3_0::IGnss;
 using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback;
 using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback;
 using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback;
@@ -248,9 +244,7 @@
 sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
 sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
 sp<IGnss_V2_1> gnssHal_V2_1 = nullptr;
-sp<IGnss_V3_0> gnssHal_V3_0 = nullptr;
 sp<IGnssAidl> gnssHalAidl = nullptr;
-sp<IGnssPsds> gnssPsdsIface = nullptr;
 sp<IGnssPsdsAidl> gnssPsdsAidlIface = nullptr;
 sp<IGnssXtra> gnssXtraIface = nullptr;
 sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
@@ -784,23 +778,17 @@
     }
 };
 
-/*
- * GnssPsdsCallback class implements the callback methods for the IGnssPsds
+/**
+ * GnssXtraCallback class implements the callback methods for the IGnssXtra
  * interface.
  */
-struct GnssPsdsCallback : public IGnssPsdsCallback {
+class GnssXtraCallback : public IGnssXtraCallback {
     Return<void> downloadRequestCb() override;
-    Return<void> downloadRequestCb_3_0(int32_t psdsType) override;
 };
 
-Return<void> GnssPsdsCallback::downloadRequestCb() {
-    return downloadRequestCb_3_0(/* psdsType= */ 1);
-}
-
-Return<void> GnssPsdsCallback::downloadRequestCb_3_0(int32_t psdsType) {
-    ALOGD("%s. psdsType: %d", __func__, psdsType);
+Return<void> GnssXtraCallback::downloadRequestCb() {
     JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType);
+    env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
     return Void();
 }
@@ -1463,17 +1451,6 @@
         ALOGD("Successfully got GNSS AIDL handle.");
     }
 
-    ALOGD("Trying IGnss_V3_0::getService()");
-    gnssHal_V3_0 = IGnss_V3_0::getService();
-    if (gnssHal_V3_0 != nullptr) {
-        gnssHal = gnssHal_V3_0;
-        gnssHal_V2_1 = gnssHal_V3_0;
-        gnssHal_V2_0 = gnssHal_V3_0;
-        gnssHal_V1_1 = gnssHal_V3_0;
-        gnssHal = gnssHal_V3_0;
-        return;
-    }
-
     ALOGD("Trying IGnss_V2_1::getService()");
     gnssHal_V2_1 = IGnss_V2_1::getService();
     if (gnssHal_V2_1 != nullptr) {
@@ -1708,13 +1685,6 @@
         } else {
             ALOGD("Unable to get a handle to PSDS AIDL interface.");
         }
-    } else if (gnssHal_V3_0 != nullptr) {
-        auto gnssPsds = gnssHal_V3_0->getExtensionPsds();
-        if (!gnssPsds.isOk()) {
-            ALOGD("Unable to get a handle to Psds");
-        } else {
-            gnssPsdsIface = gnssPsds;
-        }
     } else {
         auto gnssXtra = gnssHal->getExtensionXtra();
         if (!gnssXtra.isOk()) {
@@ -2017,20 +1987,13 @@
         if (!checkAidlStatus(status, "IGnssPsdsAidl setCallback() failed.")) {
             gnssPsdsAidlIface = nullptr;
         }
-    } else {
-        sp<IGnssPsdsCallback> gnssPsdsCbIface = new GnssPsdsCallback();
-        if (gnssPsdsIface != nullptr) {
-            result = gnssPsdsIface->setCallback_3_0(gnssPsdsCbIface);
-            if (!checkHidlReturn(result, "IGnssPsds setCallback() failed.")) {
-                gnssPsdsIface = nullptr;
-            }
-        } else if (gnssXtraIface != nullptr) {
-            result = gnssXtraIface->setCallback(gnssPsdsCbIface);
-            if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
-                gnssXtraIface = nullptr;
-            }
+    } else if (gnssXtraIface != nullptr) {
+        sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
+        result = gnssXtraIface->setCallback(gnssXtraCbIface);
+        if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
+            gnssXtraIface = nullptr;
         } else {
-            ALOGI("Unable to initialize IGnssPsds/IGnssXtra interface.");
+            ALOGI("Unable to initialize IGnssXtra interface.");
         }
     }
 
@@ -2293,16 +2256,14 @@
 }
 
 static jboolean android_location_gnss_hal_GnssNative_supports_psds(JNIEnv* /* env */, jclass) {
-    return (gnssPsdsAidlIface != nullptr || gnssPsdsIface != nullptr || gnssXtraIface != nullptr)
-            ? JNI_TRUE
-            : JNI_FALSE;
+    return (gnssPsdsAidlIface != nullptr || gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
 }
 
 static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, jclass,
                                                                   jbyteArray data, jint length,
                                                                   jint psdsType) {
-    if (gnssPsdsAidlIface == nullptr && gnssPsdsIface == nullptr && gnssXtraIface == nullptr) {
-        ALOGE("%s: IGnssPsds or IGnssXtra interface not available.", __func__);
+    if (gnssPsdsAidlIface == nullptr && gnssXtraIface == nullptr) {
+        ALOGE("%s: IGnssPsdsAidl or IGnssXtra interface not available.", __func__);
         return;
     }
 
@@ -2313,10 +2274,6 @@
                                                                              (const uint8_t*)bytes +
                                                                                      length));
         checkAidlStatus(status, "IGnssPsdsAidl injectPsdsData() failed.");
-    } else if (gnssPsdsIface != nullptr) {
-        auto result = gnssPsdsIface->injectPsdsData_3_0(psdsType,
-                                                        std::string((const char*)bytes, length));
-        checkHidlReturn(result, "IGnssPsds injectPsdsData() failed.");
     } else if (gnssXtraIface != nullptr) {
         auto result = gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
         checkHidlReturn(result, "IGnssXtra injectXtraData() failed.");
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 1cb9e57..7d705c1 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -35,6 +35,18 @@
                 </xs:element>
                 <xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0" maxOccurs="1"/>
                 <xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1" />
+                <xs:element type="nonNegativeDecimal" name="screenBrightnessRampFastDecrease">
+                    <xs:annotation name="final"/>
+                </xs:element>
+                <xs:element type="nonNegativeDecimal" name="screenBrightnessRampFastIncrease">
+                    <xs:annotation name="final"/>
+                </xs:element>
+                <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowDecrease">
+                    <xs:annotation name="final"/>
+                </xs:element>
+                <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowIncrease">
+                    <xs:annotation name="final"/>
+                </xs:element>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index e073ab3..eb3f1b7 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -7,10 +7,18 @@
     method public com.android.server.display.config.DisplayQuirks getQuirks();
     method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault();
     method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap();
+    method public final java.math.BigDecimal getScreenBrightnessRampFastDecrease();
+    method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
+    method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
+    method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
     method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
     method public void setQuirks(com.android.server.display.config.DisplayQuirks);
     method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal);
     method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap);
+    method public final void setScreenBrightnessRampFastDecrease(java.math.BigDecimal);
+    method public final void setScreenBrightnessRampFastIncrease(java.math.BigDecimal);
+    method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
+    method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
   }
 
   public class DisplayQuirks {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index c9f91de..1194099 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.app.admin.DevicePolicySafetyChecker;
+import android.app.admin.FullyManagedDeviceProvisioningParams;
 import android.app.admin.IDevicePolicyManager;
 import android.app.admin.ManagedProfileProvisioningParams;
 import android.content.ComponentName;
@@ -122,4 +123,8 @@
             @NonNull ManagedProfileProvisioningParams provisioningParams) {
         return null;
     }
+
+    public void provisionFullyManagedDevice(
+            FullyManagedDeviceProvisioningParams provisioningParams) {
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ea40bdb..12b3f40 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -24,6 +24,7 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 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;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
 import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
@@ -36,6 +37,7 @@
 import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER;
 import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT;
 import static android.app.admin.DevicePolicyManager.CODE_OK;
+import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS;
 import static android.app.admin.DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER;
 import static android.app.admin.DevicePolicyManager.CODE_SYSTEM_USER;
 import static android.app.admin.DevicePolicyManager.CODE_USER_HAS_PROFILE_OWNER;
@@ -88,7 +90,9 @@
 import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_ADMIN_PACKAGE_INSTALLATION_FAILED;
 import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_PRE_CONDITION_FAILED;
 import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_PROFILE_CREATION_FAILED;
+import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_REMOVE_NON_REQUIRED_APPS_FAILED;
 import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED;
+import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED;
 import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_STARTING_PROFILE_FAILED;
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
@@ -159,6 +163,7 @@
 import android.app.admin.DevicePolicySafetyChecker;
 import android.app.admin.DeviceStateCache;
 import android.app.admin.FactoryResetProtectionPolicy;
+import android.app.admin.FullyManagedDeviceProvisioningParams;
 import android.app.admin.ManagedProfileProvisioningParams;
 import android.app.admin.NetworkEvent;
 import android.app.admin.PasswordMetrics;
@@ -281,6 +286,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.LocalePicker;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.net.NetworkUtilsInternal;
@@ -339,6 +345,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -395,6 +402,8 @@
 
     private static final String NULL_STRING_ARRAY = "nullStringArray";
 
+    private static final String ALLOW_USER_PROVISIONING_KEY = "ro.config.allowuserprovisioning";
+
     // Comprehensive list of delegations.
     private static final String DELEGATIONS[] = {
         DELEGATION_CERT_INSTALL,
@@ -12685,6 +12694,9 @@
             logMissingFeatureAction("Cannot check provisioning for action " + action);
             return CODE_DEVICE_ADMIN_NOT_SUPPORTED;
         }
+        if (!isProvisioningAllowed()) {
+            return CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS;
+        }
         final int code = checkProvisioningPreConditionSkipPermissionNoLog(action, packageName);
         if (code != CODE_OK) {
             Slog.d(LOG_TAG, "checkProvisioningPreCondition(" + action + ", " + packageName
@@ -12694,6 +12706,23 @@
         return code;
     }
 
+    /**
+     *  Checks if provisioning is allowed during regular usage (non-developer/CTS). This could
+     *  return {@code false} if the device has an overlaid config value set to false. If not set,
+     *  the default is true.
+     */
+    private boolean isProvisioningAllowed() {
+        boolean isDeveloperMode = isDeveloperMode(mContext);
+        boolean isProvisioningAllowedForNormalUsers = SystemProperties.getBoolean(
+                ALLOW_USER_PROVISIONING_KEY, /* defValue= */ true);
+
+        return isDeveloperMode || isProvisioningAllowedForNormalUsers;
+    }
+
+    private static boolean isDeveloperMode(Context context) {
+        return Global.getInt(context.getContentResolver(), Global.ADB_ENABLED, 0) > 0;
+    }
+
     private int checkProvisioningPreConditionSkipPermissionNoLog(String action,
             String packageName) {
         final int callingUserId = mInjector.userHandleGetCallingUserId();
@@ -12850,14 +12879,11 @@
                         callingUserHandle, hasDeviceOwner));
                 return CODE_CANNOT_ADD_MANAGED_PROFILE;
             }
-            // If there's a restriction on removing the managed profile then we have to take it
-            // into account when checking whether more profiles can be added.
-            boolean canRemoveProfile =
-                    !mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
-                    callingUserHandle);
-            if (!mUserManager.canAddMoreManagedProfiles(callingUserId, canRemoveProfile)) {
-                Slog.i(LOG_TAG, String.format(
-                        "Cannot add more profiles: Can remove current? %b", canRemoveProfile));
+
+            // Bail out if we are trying to provision a work profile but one already exists.
+            if (!mUserManager.canAddMoreManagedProfiles(
+                    callingUserId, /* allowedToRemoveOne= */ false)) {
+                Slog.i(LOG_TAG, String.format("A work profile already exists."));
                 return CODE_CANNOT_ADD_MANAGED_PROFILE;
             }
         } finally {
@@ -16115,10 +16141,15 @@
     private boolean enableAdminAndSetProfileOwner(
             @UserIdInt int userId, @UserIdInt int callingUserId, ComponentName adminComponent,
             String ownerName) {
+        enableAndSetActiveAdmin(userId, callingUserId, adminComponent);
+        return setProfileOwner(adminComponent, ownerName, userId);
+    }
+
+    private void enableAndSetActiveAdmin(
+            @UserIdInt int userId, @UserIdInt int callingUserId, ComponentName adminComponent) {
         final String adminPackage = adminComponent.getPackageName();
         enablePackage(adminPackage, callingUserId);
         setActiveAdmin(adminComponent, /* refreshing= */ true, userId);
-        return setProfileOwner(adminComponent, ownerName, userId);
     }
 
     private void enablePackage(String packageName, @UserIdInt int userId) {
@@ -16252,4 +16283,134 @@
                 UserHandle.of(profileId), /* flags= */ 0);
         return profileContext.getSystemService(DevicePolicyManager.class);
     }
+
+    @Override
+    public void provisionFullyManagedDevice(
+            FullyManagedDeviceProvisioningParams provisioningParams) {
+        ComponentName deviceAdmin = provisioningParams.getDeviceAdminComponentName();
+
+        Objects.requireNonNull(deviceAdmin, "admin is null.");
+        Objects.requireNonNull(provisioningParams.getOwnerName(), "owner name is null.");
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            int result = checkProvisioningPreConditionSkipPermission(
+                    ACTION_PROVISION_MANAGED_DEVICE, deviceAdmin.getPackageName());
+            if (result != CODE_OK) {
+                throw new ServiceSpecificException(
+                        PROVISIONING_RESULT_PRE_CONDITION_FAILED,
+                        "Provisioning preconditions failed with result: " + result);
+            }
+
+            setTimeAndTimezone(provisioningParams.getTimeZone(), provisioningParams.getLocalTime());
+            setLocale(provisioningParams.getLocale());
+
+            if (!removeNonRequiredAppsForManagedDevice(
+                    caller.getUserId(),
+                    provisioningParams.isLeaveAllSystemAppsEnabled(),
+                    deviceAdmin)) {
+                throw new ServiceSpecificException(
+                        PROVISIONING_RESULT_REMOVE_NON_REQUIRED_APPS_FAILED,
+                        "PackageManager failed to remove non required apps.");
+            }
+
+            if (!setActiveAdminAndDeviceOwner(
+                    caller.getUserId(), deviceAdmin, provisioningParams.getOwnerName())) {
+                throw new ServiceSpecificException(
+                        PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED,
+                        "Failed to set device owner.");
+            }
+
+            disallowAddUser();
+
+            final Intent intent = new Intent(DevicePolicyManager.ACTION_PROVISIONED_MANAGED_DEVICE)
+                    .putExtra(Intent.EXTRA_USER_HANDLE, caller.getUserId())
+                    .putExtra(
+                            DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
+                            provisioningParams.isLeaveAllSystemAppsEnabled())
+                    .setPackage(getManagedProvisioningPackage(mContext))
+                    .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+            mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void setTimeAndTimezone(String timeZone, long localTime) {
+        try {
+            final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+            if (timeZone != null) {
+                alarmManager.setTimeZone(timeZone);
+            }
+            if (localTime > 0) {
+                alarmManager.setTime(localTime);
+            }
+        } catch (Exception e) {
+            // Do not stop provisioning and ignore this error.
+            Slog.e(LOG_TAG, "Alarm manager failed to set the system time/timezone.", e);
+        }
+    }
+
+    private void setLocale(Locale locale) {
+        if (locale == null || locale.equals(Locale.getDefault())) {
+            return;
+        }
+        try {
+            // If locale is different from current locale this results in a configuration change,
+            // which will trigger the restarting of the activity.
+            LocalePicker.updateLocale(locale);
+        } catch (Exception e) {
+            // Do not stop provisioning and ignore this error.
+            Slog.e(LOG_TAG, "Failed to set the system locale.", e);
+        }
+    }
+
+    private boolean removeNonRequiredAppsForManagedDevice(
+            int userId, boolean leaveAllSystemAppsEnabled, ComponentName admin) {
+        Set<String> packagesToDelete = leaveAllSystemAppsEnabled
+                ? Collections.emptySet()
+                : mOverlayPackagesProvider.getNonRequiredApps(
+                        admin, userId, ACTION_PROVISION_MANAGED_DEVICE);
+        if (packagesToDelete.isEmpty()) {
+            return true;
+        }
+        NonRequiredPackageDeleteObserver packageDeleteObserver =
+                new NonRequiredPackageDeleteObserver(packagesToDelete.size());
+        for (String packageName : packagesToDelete) {
+            if (isPackageInstalledForUser(packageName, userId)) {
+                Slog.i(LOG_TAG, "Deleting package [" + packageName + "] as user " + userId);
+                mContext.getPackageManager().deletePackageAsUser(
+                        packageName,
+                        packageDeleteObserver,
+                        PackageManager.DELETE_SYSTEM_APP,
+                        userId);
+            }
+        }
+        Slog.i(LOG_TAG, "Waiting for non required apps to be deleted");
+        return packageDeleteObserver.awaitPackagesDeletion();
+    }
+
+    private void disallowAddUser() {
+        if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+            Slog.i(LOG_TAG, "Not setting DISALLOW_ADD_USER on headless system user mode.");
+            return;
+        }
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            UserHandle userHandle = userInfo.getUserHandle();
+            if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER, userHandle)) {
+                mUserManager.setUserRestriction(
+                        UserManager.DISALLOW_ADD_USER, /* value= */ true, userHandle);
+            }
+        }
+    }
+
+    private boolean setActiveAdminAndDeviceOwner(
+            @UserIdInt int userId, ComponentName adminComponent, String name) {
+        enableAndSetActiveAdmin(userId, userId, adminComponent);
+        return setDeviceOwner(adminComponent, name, userId);
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
new file mode 100644
index 0000000..0e448cd
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.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.devicepolicy;
+
+import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
+
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.PackageManager;
+import android.util.Log;
+import android.util.Slog;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Awaits the deletion of all the non-required apps.
+ */
+final class NonRequiredPackageDeleteObserver extends IPackageDeleteObserver.Stub {
+    private static final int PACKAGE_DELETE_TIMEOUT_SEC = 30;
+
+    private final AtomicInteger mPackageCount = new AtomicInteger(/* initialValue= */ 0);
+    private final CountDownLatch mLatch;
+    private boolean mSuccess;
+
+    NonRequiredPackageDeleteObserver(int packageCount) {
+        this.mLatch = new CountDownLatch(packageCount);
+        this.mPackageCount.set(packageCount);
+    }
+
+    @Override
+    public void packageDeleted(String packageName, int returnCode) {
+        if (returnCode != PackageManager.DELETE_SUCCEEDED) {
+            Slog.e(LOG_TAG, "Failed to delete package: " + packageName);
+            mLatch.notifyAll();
+            return;
+        }
+        int currentPackageCount = mPackageCount.decrementAndGet();
+        if (currentPackageCount == 0) {
+            mSuccess = true;
+            Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
+                    + "and all disallowed apps have been uninstalled.");
+        }
+        mLatch.countDown();
+    }
+
+    public boolean awaitPackagesDeletion() {
+        try {
+            mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Log.w(LOG_TAG, "Interrupted while waiting for package deletion", e);
+            Thread.currentThread().interrupt();
+        }
+        return mSuccess;
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c613dfb..7839274 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -160,7 +160,7 @@
 import com.android.server.pm.dex.SystemServerDexLoadReporter;
 import com.android.server.policy.PermissionPolicyService;
 import com.android.server.policy.PhoneWindowManager;
-import com.android.server.policy.role.LegacyRoleStateProviderImpl;
+import com.android.server.policy.role.RoleServicePlatformHelperImpl;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
 import com.android.server.power.ThermalManagerService;
@@ -168,7 +168,7 @@
 import com.android.server.profcollect.ProfcollectForwardingService;
 import com.android.server.recoverysystem.RecoverySystemService;
 import com.android.server.restrictions.RestrictionsManagerService;
-import com.android.server.role.RoleManagerService;
+import com.android.server.role.RoleServicePlatformHelper;
 import com.android.server.security.FileIntegrityService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
@@ -353,6 +353,7 @@
             "com.android.server.ConnectivityServiceInitializer";
     private static final String IP_CONNECTIVITY_METRICS_CLASS =
             "com.android.server.connectivity.IpConnectivityMetrics";
+    private static final String ROLE_SERVICE_CLASS = "com.android.server.role.RoleService";
 
     private static final String TETHERING_CONNECTOR_CLASS = "android.net.ITetheringConnector";
 
@@ -2032,8 +2033,9 @@
 
             // Grants default permissions and defines roles
             t.traceBegin("StartRoleManagerService");
-            mSystemServiceManager.startService(new RoleManagerService(
-                    mSystemContext, new LegacyRoleStateProviderImpl(mSystemContext)));
+            LocalManagerRegistry.addManager(RoleServicePlatformHelper.class,
+                    new RoleServicePlatformHelperImpl(mSystemContext));
+            mSystemServiceManager.startService(ROLE_SERVICE_CLASS);
             t.traceEnd();
 
             // We need to always start this service, regardless of whether the
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 c6fb37d..8d744c4 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
@@ -16,6 +16,8 @@
 
 package com.android.server.appsearch.external.localstorage;
 
+import static android.app.appsearch.AppSearchResult.RESULT_OK;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.testng.Assert.expectThrows;
@@ -25,6 +27,7 @@
 import android.app.appsearch.SearchResult;
 import android.app.appsearch.SearchResultPage;
 import android.app.appsearch.SearchSpec;
+import android.app.appsearch.SetSchemaResult;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.content.Context;
 import android.util.ArraySet;
@@ -68,7 +71,7 @@
                 AppSearchImpl.create(
                         mTemporaryFolder.newFolder(),
                         context,
-                        /*userId=*/-1,
+                        VisibilityStore.NO_OP_USER_ID,
                         /*globalQuerierPackage
                         =*/ context.getPackageName());
     }
@@ -746,6 +749,54 @@
     }
 
     @Test
+    public void testSetSchema_incompatible() throws Exception {
+        List<SchemaTypeConfigProto> existingSchemas =
+                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
+
+        List<AppSearchSchema> oldSchemas = new ArrayList<>();
+        oldSchemas.add(
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new AppSearchSchema.StringPropertyConfig.Builder("foo")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .setTokenizerType(
+                                                AppSearchSchema.StringPropertyConfig
+                                                        .TOKENIZER_TYPE_PLAIN)
+                                        .setIndexingType(
+                                                AppSearchSchema.StringPropertyConfig
+                                                        .INDEXING_TYPE_PREFIXES)
+                                        .build())
+                        .build());
+        oldSchemas.add(new AppSearchSchema.Builder("Text").build());
+        // Set schema Email to AppSearch database1
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                oldSchemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                /*forceOverride=*/ false);
+
+        // Create incompatible schema
+        List<AppSearchSchema> newSchemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+
+        // set email incompatible and delete text
+        SetSchemaResult setSchemaResult =
+                mAppSearchImpl.setSchema(
+                        "package",
+                        "database1",
+                        newSchemas,
+                        /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                        /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                        /*forceOverride=*/ true);
+        assertThat(setSchemaResult.getDeletedSchemaTypes()).containsExactly("Text");
+        assertThat(setSchemaResult.getIncompatibleSchemaTypes()).containsExactly("Email");
+        assertThat(setSchemaResult.getResultCode()).isEqualTo(RESULT_OK);
+    }
+
+    @Test
     public void testRemoveSchema() throws Exception {
         List<SchemaTypeConfigProto> existingSchemas =
                 mAppSearchImpl.getSchemaProtoLocked().getTypesList();
@@ -785,20 +836,17 @@
 
         final List<AppSearchSchema> finalSchemas =
                 Collections.singletonList(new AppSearchSchema.Builder("Email").build());
-        // Check the incompatible error has been thrown.
-        AppSearchException e =
-                expectThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.setSchema(
-                                        "package",
-                                        "database1",
-                                        finalSchemas,
-                                        /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
-                                        /*schemasPackageAccessible=*/ Collections.emptyMap(),
-                                        /*forceOverride=*/ false));
-        assertThat(e).hasMessageThat().contains("Schema is incompatible");
-        assertThat(e).hasMessageThat().contains("Deleted types: [package$database1/Document]");
+        SetSchemaResult setSchemaResult =
+                mAppSearchImpl.setSchema(
+                        "package",
+                        "database1",
+                        finalSchemas,
+                        /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                        /*schemasPackageAccessible=*/ Collections.emptyMap(),
+                        /*forceOverride=*/ false);
+
+        // Check the Document type has been deleted.
+        assertThat(setSchemaResult.getDeletedSchemaTypes()).containsExactly("Document");
 
         // ForceOverride to delete.
         mAppSearchImpl.setSchema(
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index 4ecaac5..79a5ed6 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -17,6 +17,7 @@
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -27,6 +28,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.Intent;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.util.Log;
@@ -58,7 +60,7 @@
     @Mock private AudioService mMockAudioService;
     @Spy private AudioDeviceInventory mSpyDevInventory;
     @Spy private AudioSystemAdapter mSpyAudioSystem;
-    private SystemServerAdapter mSystemServer;
+    @Spy private SystemServerAdapter mSpySystemServer;
 
     private BluetoothDevice mFakeBtDevice;
 
@@ -69,9 +71,9 @@
         mMockAudioService = mock(AudioService.class);
         mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
         mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem));
-        mSystemServer = new NoOpSystemServerAdapter();
+        mSpySystemServer = spy(new NoOpSystemServerAdapter());
         mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory,
-                mSystemServer);
+                mSpySystemServer);
         mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker);
 
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -172,6 +174,30 @@
                 true);
     }
 
+    /**
+     * Test that device wired state intents are broadcasted on connection state change
+     * @throws Exception
+     */
+    @Test
+    public void testSetWiredDeviceConnectionState() throws Exception {
+        Log.i(TAG, "starting postSetWiredDeviceConnectionState");
+
+        final String address = "testAddress";
+        final String name = "testName";
+        final String caller = "testCaller";
+
+        doNothing().when(mSpySystemServer).broadcastStickyIntentToCurrentProfileGroup(
+                any(Intent.class));
+
+        mSpyDevInventory.setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+                AudioService.CONNECTION_STATE_CONNECTED, address, name, caller);
+        Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
+
+        // Verify that the sticky intent is broadcasted
+        verify(mSpySystemServer, times(1)).broadcastStickyIntentToCurrentProfileGroup(
+                any(Intent.class));
+    }
+
     private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection,
             boolean mockMediaPlayback, boolean guaranteeSingleConnection) throws Exception {
         when(mMockAudioService.getDeviceForStream(AudioManager.STREAM_MUSIC))
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 065a2f3..2e97a8d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -31,6 +31,7 @@
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.PasswordMetrics.computeForPassword;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
+import static android.net.InetAddresses.parseNumericAddress;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
@@ -66,6 +67,8 @@
 import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 import static org.testng.Assert.assertThrows;
 
+import static java.util.Collections.emptyList;
+
 import android.Manifest.permission;
 import android.app.Activity;
 import android.app.AppOpsManager;
@@ -126,6 +129,8 @@
 import org.mockito.stubbing.Answer;
 
 import java.io.File;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -2360,6 +2365,49 @@
     }
 
     @Test
+    public void testGetProxyParameters() throws Exception {
+        assertThat(dpm.getProxyParameters(inetAddrProxy("192.0.2.1", 1234), emptyList()))
+                .isEqualTo(new Pair<>("192.0.2.1:1234", ""));
+        assertThat(dpm.getProxyParameters(inetAddrProxy("192.0.2.1", 1234),
+                listOf("one.example.com  ", "  two.example.com ")))
+                .isEqualTo(new Pair<>("192.0.2.1:1234", "one.example.com,two.example.com"));
+        assertThat(dpm.getProxyParameters(hostnameProxy("proxy.example.com", 1234), emptyList()))
+                .isEqualTo(new Pair<>("proxy.example.com:1234", ""));
+        assertThat(dpm.getProxyParameters(hostnameProxy("proxy.example.com", 1234),
+                listOf("excluded.example.com")))
+                .isEqualTo(new Pair<>("proxy.example.com:1234", "excluded.example.com"));
+
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                inetAddrProxy("192.0.2.1", 0), emptyList()));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("", 1234), emptyList()));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("", 0), emptyList()));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("invalid! hostname", 1234), emptyList()));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("proxy.example.com", 1234), listOf("invalid exclusion")));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("proxy.example.com", -1), emptyList()));
+        assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters(
+                hostnameProxy("proxy.example.com", 0xFFFF + 1), emptyList()));
+    }
+
+    private static Proxy inetAddrProxy(String inetAddr, int port) {
+        return new Proxy(
+                Proxy.Type.HTTP, new InetSocketAddress(parseNumericAddress(inetAddr), port));
+    }
+
+    private static Proxy hostnameProxy(String hostname, int port) {
+        return new Proxy(
+                Proxy.Type.HTTP, InetSocketAddress.createUnresolved(hostname, port));
+    }
+
+    private static List<String> listOf(String... args) {
+        return Arrays.asList(args);
+    }
+
+    @Test
     public void testSetKeyguardDisabledFeaturesWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3289,7 +3337,7 @@
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false);
         initializeDpms();
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -3331,7 +3379,7 @@
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false);
         initializeDpms();
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -3395,7 +3443,7 @@
         when(getServices().ipackageManager
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
         when(getServices().userManager.getProfileParent(UserHandle.USER_SYSTEM)).thenReturn(null);
@@ -3439,7 +3487,7 @@
         when(getServices().ipackageManager
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(true);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
         when(getServices().userManager.getProfileParent(UserHandle.USER_SYSTEM)).thenReturn(null);
@@ -3459,8 +3507,6 @@
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
-                true)).thenReturn(true);
     }
 
     @Test
@@ -3620,7 +3666,7 @@
         when(getServices().ipackageManager
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(false);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -3664,7 +3710,7 @@
         when(getServices().ipackageManager
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -3711,7 +3757,7 @@
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
-                true)).thenReturn(true);
+                false)).thenReturn(true);
         setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -3753,7 +3799,7 @@
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
-                true)).thenReturn(true);
+                false)).thenReturn(true);
         setUserSetupCompleteForUser(true, CALLER_USER_HANDLE);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -3800,7 +3846,7 @@
         when(getServices().ipackageManager
                 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -3835,7 +3881,7 @@
         when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE))
             .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
-                true)).thenReturn(true);
+                false)).thenReturn(true);
         setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
 
         mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
@@ -3861,7 +3907,7 @@
                 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
     }
 
-    private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
+    private void setup_provisionManagedProfileOneAlreadyExist_primaryUser() throws Exception {
         setDeviceOwner();
 
         when(getServices().ipackageManager
@@ -3873,26 +3919,24 @@
                 .thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
-                true)).thenReturn(true);
         setUserSetupCompleteForUser(false, CALLER_USER_HANDLE);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
     }
 
     @Test
-    public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
+    public void testIsProvisioningAllowed_provisionManagedProfile_oneAlreadyExists_primaryUser()
             throws Exception {
-        setup_provisionManagedProfileCantRemoveUser_primaryUser();
+        setup_provisionManagedProfileOneAlreadyExist_primaryUser();
         mContext.packageName = admin1.getPackageName();
         setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
     }
 
     @Test
-    public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser()
+    public void testCheckProvisioningPreCondition_provisionManagedProfile_oneAlreadyExists_primaryUser()
             throws Exception {
-        setup_provisionManagedProfileCantRemoveUser_primaryUser();
+        setup_provisionManagedProfileOneAlreadyExist_primaryUser();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
                 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
@@ -5494,7 +5538,7 @@
         // Attempt to set to empty list (which means no listener is allowlisted)
         mContext.binder.callingUid = adminUid;
         assertThat(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList())).isFalse();
+                admin1, emptyList())).isFalse();
         assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -5588,7 +5632,7 @@
         // Setting an empty allowlist - only system listeners allowed
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertThat(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList())).isTrue();
+                admin1, emptyList())).isTrue();
         assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -5653,7 +5697,7 @@
         // all allowed in primary profile
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertThat(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList())).isTrue();
+                admin1, emptyList())).isTrue();
         assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
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 0cf0af3..75bf1e6 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
@@ -19,6 +19,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.fail;
+
 import android.content.Context;
 import android.os.FileUtils;
 import android.platform.test.annotations.Presubmit;
@@ -35,7 +37,12 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 @Presubmit
 @SmallTest
@@ -44,17 +51,63 @@
 
     /**
      * A {@link UpdatableFontDir.FontFileParser} for testing. Instead of using real font files,
-     * this test uses fake font files. A fake font file has its version as its file content.
+     * this test uses fake font files. A fake font file has its PostScript naem and revision as the
+     * file content.
      */
     private static class FakeFontFileParser implements UpdatableFontDir.FontFileParser {
         @Override
-        public long getVersion(File file) throws IOException {
-            return Long.parseLong(FileUtils.readTextFile(file, 100, ""));
+        public String getPostScriptName(File file) throws IOException {
+            String content = FileUtils.readTextFile(file, 100, "");
+            return content.split(",")[0];
+        }
+
+        @Override
+        public long getRevision(File file) throws IOException {
+            String content = FileUtils.readTextFile(file, 100, "");
+            return Long.parseLong(content.split(",")[1]);
+        }
+    }
+
+    // FakeFsverityUtil will successfully set up fake fs-verity if the signature is GOOD_SIGNATURE.
+    private static final String GOOD_SIGNATURE = "Good signature";
+
+    /** A fake FsverityUtil to keep fake verity bit in memory. */
+    private static class FakeFsverityUtil implements UpdatableFontDir.FsverityUtil {
+        private final Set<String> mHasFsverityPaths = new HashSet<>();
+
+        public void remove(String name) {
+            mHasFsverityPaths.remove(name);
+        }
+
+        @Override
+        public boolean hasFsverity(String path) {
+            return mHasFsverityPaths.contains(path);
+        }
+
+        @Override
+        public void setUpFsverity(String path, byte[] pkcs7Signature) throws IOException {
+            String fakeSignature = new String(pkcs7Signature, StandardCharsets.UTF_8);
+            if (GOOD_SIGNATURE.equals(fakeSignature)) {
+                mHasFsverityPaths.add(path);
+            } else {
+                throw new IOException("Failed to set up fake fs-verity");
+            }
+        }
+
+        @Override
+        public boolean rename(File src, File dest) {
+            if (src.renameTo(dest)) {
+                mHasFsverityPaths.remove(src.getAbsolutePath());
+                mHasFsverityPaths.add(dest.getAbsolutePath());
+                return true;
+            }
+            return false;
         }
     }
 
     private File mCacheDir;
     private File mUpdatableFontFilesDir;
+    private List<File> mPreinstalledFontDirs;
 
     @SuppressWarnings("ResultOfMethodCallIgnored")
     @Before
@@ -65,6 +118,12 @@
         mCacheDir.mkdirs();
         mUpdatableFontFilesDir = new File(mCacheDir, "updatable_fonts");
         mUpdatableFontFilesDir.mkdir();
+        mPreinstalledFontDirs = new ArrayList<>();
+        mPreinstalledFontDirs.add(new File(mCacheDir, "system_fonts"));
+        mPreinstalledFontDirs.add(new File(mCacheDir, "product_fonts"));
+        for (File dir : mPreinstalledFontDirs) {
+            dir.mkdir();
+        }
     }
 
     @After
@@ -75,19 +134,22 @@
     @Test
     public void construct() throws Exception {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dirForPreparation = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
-        installFontFile(dirForPreparation, "foo.ttf", "1");
-        installFontFile(dirForPreparation, "bar.ttf", "2");
-        installFontFile(dirForPreparation, "foo.ttf", "3");
-        installFontFile(dirForPreparation, "bar.ttf", "4");
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dirForPreparation = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,4", GOOD_SIGNATURE);
         // Four font dirs are created.
         assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
 
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
         assertThat(dir.getFontFileMap()).containsKey("foo.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(3);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(3);
         assertThat(dir.getFontFileMap()).containsKey("bar.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("bar.ttf"))).isEqualTo(4);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("bar.ttf"))).isEqualTo(4);
         // Outdated font dir should be deleted.
         assertThat(mUpdatableFontFilesDir.list()).hasLength(2);
     }
@@ -95,66 +157,189 @@
     @Test
     public void construct_empty() {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
         assertThat(dir.getFontFileMap()).isEmpty();
     }
 
     @Test
+    public void construct_missingFsverity() throws Exception {
+        FakeFontFileParser parser = new FakeFontFileParser();
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dirForPreparation = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,4", GOOD_SIGNATURE);
+        // Four font dirs are created.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
+
+        fakeFsverityUtil.remove(
+                dirForPreparation.getFontFileMap().get("foo.ttf").getAbsolutePath());
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        assertThat(dir.getFontFileMap()).isEmpty();
+        // All font dirs (including dir for "bar.ttf") should be deleted.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
+    }
+
+    @Test
+    public void construct_fontNameMismatch() throws Exception {
+        FakeFontFileParser parser = new FakeFontFileParser();
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dirForPreparation = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,4", GOOD_SIGNATURE);
+        // Four font dirs are created.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
+
+        // Overwrite "foo.ttf" with wrong contents.
+        FileUtils.stringToFile(dirForPreparation.getFontFileMap().get("foo.ttf"), "bar,4");
+
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        assertThat(dir.getFontFileMap()).isEmpty();
+        // All font dirs (including dir for "bar.ttf") should be deleted.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
+    }
+
+    @Test
+    public void construct_olderThanPreinstalledFont() throws Exception {
+        FakeFontFileParser parser = new FakeFontFileParser();
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dirForPreparation = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
+        installFontFile(dirForPreparation, "bar,4", GOOD_SIGNATURE);
+        // Four font dirs are created.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
+
+        // Add preinstalled fonts.
+        FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "foo.ttf"), "foo,5");
+        FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "bar.ttf"), "bar,1");
+        FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(1), "bar.ttf"), "bar,2");
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+        // For foo.ttf, preinstalled font (revision 5) should be used.
+        assertThat(dir.getFontFileMap()).doesNotContainKey("foo.ttf");
+        // For bar.ttf, updated font (revision 4) should be used.
+        assertThat(dir.getFontFileMap()).containsKey("bar.ttf");
+        assertThat(parser.getRevision(dir.getFontFileMap().get("bar.ttf"))).isEqualTo(4);
+        // Outdated font dir should be deleted.
+        // We don't delete bar.ttf in this case, because it's normal that OTA updates preinstalled
+        // fonts.
+        assertThat(mUpdatableFontFilesDir.list()).hasLength(1);
+    }
+
+    @Test
     public void installFontFile() throws Exception {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
 
-        installFontFile(dir, "test.ttf", "1");
+        installFontFile(dir, "test,1", GOOD_SIGNATURE);
         assertThat(dir.getFontFileMap()).containsKey("test.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("test.ttf"))).isEqualTo(1);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("test.ttf"))).isEqualTo(1);
     }
 
     @Test
     public void installFontFile_upgrade() throws Exception {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
 
-        installFontFile(dir, "test.ttf", "1");
+        installFontFile(dir, "test,1", GOOD_SIGNATURE);
         Map<String, File> mapBeforeUpgrade = dir.getFontFileMap();
-        installFontFile(dir, "test.ttf", "2");
+        installFontFile(dir, "test,2", GOOD_SIGNATURE);
         assertThat(dir.getFontFileMap()).containsKey("test.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("test.ttf"))).isEqualTo(2);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("test.ttf"))).isEqualTo(2);
         assertThat(mapBeforeUpgrade).containsKey("test.ttf");
         assertWithMessage("Older fonts should not be deleted until next loadFontFileMap")
-                .that(parser.getVersion(mapBeforeUpgrade.get("test.ttf"))).isEqualTo(1);
+                .that(parser.getRevision(mapBeforeUpgrade.get("test.ttf"))).isEqualTo(1);
     }
 
     @Test
     public void installFontFile_downgrade() throws Exception {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
 
-        installFontFile(dir, "test.ttf", "2");
-        installFontFile(dir, "test.ttf", "1");
+        installFontFile(dir, "test,2", GOOD_SIGNATURE);
+        try {
+            installFontFile(dir, "test,1", GOOD_SIGNATURE);
+            fail("Expect IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expect
+        }
         assertThat(dir.getFontFileMap()).containsKey("test.ttf");
-        assertWithMessage("Font should not be downgraded to an older version")
-                .that(parser.getVersion(dir.getFontFileMap().get("test.ttf"))).isEqualTo(2);
+        assertWithMessage("Font should not be downgraded to an older revision")
+                .that(parser.getRevision(dir.getFontFileMap().get("test.ttf"))).isEqualTo(2);
     }
 
     @Test
     public void installFontFile_multiple() throws Exception {
         FakeFontFileParser parser = new FakeFontFileParser();
-        UpdatableFontDir dir = new UpdatableFontDir(mUpdatableFontFilesDir, parser);
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
 
-        installFontFile(dir, "foo.ttf", "1");
-        installFontFile(dir, "bar.ttf", "2");
+        installFontFile(dir, "foo,1", GOOD_SIGNATURE);
+        installFontFile(dir, "bar,2", GOOD_SIGNATURE);
         assertThat(dir.getFontFileMap()).containsKey("foo.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(1);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(1);
         assertThat(dir.getFontFileMap()).containsKey("bar.ttf");
-        assertThat(parser.getVersion(dir.getFontFileMap().get("bar.ttf"))).isEqualTo(2);
+        assertThat(parser.getRevision(dir.getFontFileMap().get("bar.ttf"))).isEqualTo(2);
     }
 
-    private void installFontFile(UpdatableFontDir dir, String name, String content)
+    @Test
+    public void installFontFile_invalidSignature() {
+        FakeFontFileParser parser = new FakeFontFileParser();
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+
+        try {
+            installFontFile(dir, "test,1", "Invalid signature");
+            fail("Expect IOException");
+        } catch (IOException e) {
+            // Expect
+        }
+        assertThat(dir.getFontFileMap()).isEmpty();
+    }
+
+    @Test
+    public void installFontFile_olderThanPreinstalledFont() throws Exception {
+        FakeFontFileParser parser = new FakeFontFileParser();
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test,1");
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil);
+
+        try {
+            installFontFile(dir, "test,1", GOOD_SIGNATURE);
+            fail("Expect IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expect
+        }
+        assertThat(dir.getFontFileMap()).isEmpty();
+    }
+
+    private void installFontFile(UpdatableFontDir dir, String content, String signature)
             throws IOException {
-        File file = File.createTempFile(name, "", mCacheDir);
+        File file = File.createTempFile("font", "ttf", mCacheDir);
         FileUtils.stringToFile(file, content);
         try (FileInputStream in = new FileInputStream(file)) {
-            dir.installFontFile(name, in.getFD());
+            dir.installFontFile(in.getFD(), signature.getBytes());
         }
     }
 }
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 b190339..395b643 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -219,8 +219,8 @@
         mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ true,
                 asHandle(currentUser));
         try {
-            assertThat(mUserManager.removeUserOrSetEphemeral(user1.id)).isEqualTo(
-                    UserManager.REMOVE_RESULT_ERROR);
+            assertThat(mUserManager.removeUserOrSetEphemeral(user1.id,
+                    /* evenWhenDisallowed= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ false,
                     asHandle(currentUser));
@@ -232,9 +232,32 @@
 
     @MediumTest
     @Test
+    public void testRemoveUserOrSetEphemeral_evenWhenRestricted() throws Exception {
+        final int currentUser = ActivityManager.getCurrentUser();
+        final UserInfo user1 = createUser("User 1", /* flags= */ 0);
+        mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ true,
+                asHandle(currentUser));
+        try {
+            synchronized (mUserRemoveLock) {
+                assertThat(mUserManager.removeUserOrSetEphemeral(user1.id,
+                        /* evenWhenDisallowed= */ true))
+                                .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
+                waitForUserRemovalLocked(user1.id);
+            }
+
+        } finally {
+            mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ false,
+                    asHandle(currentUser));
+        }
+
+        assertThat(hasUser(user1.id)).isFalse();
+    }
+
+    @MediumTest
+    @Test
     public void testRemoveUserOrSetEphemeral_systemUserReturnsError() throws Exception {
-        assertThat(mUserManager.removeUserOrSetEphemeral(UserHandle.USER_SYSTEM)).isEqualTo(
-                UserManager.REMOVE_RESULT_ERROR);
+        assertThat(mUserManager.removeUserOrSetEphemeral(UserHandle.USER_SYSTEM,
+                /* evenWhenDisallowed= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
 
         assertThat(hasUser(UserHandle.USER_SYSTEM)).isTrue();
     }
@@ -243,8 +266,8 @@
     @Test
     public void testRemoveUserOrSetEphemeral_invalidUserReturnsError() throws Exception {
         assertThat(hasUser(Integer.MAX_VALUE)).isFalse();
-        assertThat(mUserManager.removeUserOrSetEphemeral(Integer.MAX_VALUE)).isEqualTo(
-                UserManager.REMOVE_RESULT_ERROR);
+        assertThat(mUserManager.removeUserOrSetEphemeral(Integer.MAX_VALUE,
+                /* evenWhenDisallowed= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
     }
 
     @MediumTest
@@ -255,8 +278,8 @@
         // Switch to the user just created.
         switchUser(user1.id, null, /* ignoreHandle= */ true);
 
-        assertThat(mUserManager.removeUserOrSetEphemeral(user1.id)).isEqualTo(
-                UserManager.REMOVE_RESULT_SET_EPHEMERAL);
+        assertThat(mUserManager.removeUserOrSetEphemeral(user1.id, /* evenWhenDisallowed= */ false))
+                .isEqualTo(UserManager.REMOVE_RESULT_SET_EPHEMERAL);
 
         assertThat(hasUser(user1.id)).isTrue();
         assertThat(getUser(user1.id).isEphemeral()).isTrue();
@@ -276,8 +299,8 @@
     public void testRemoveUserOrSetEphemeral_nonCurrentUserRemoved() throws Exception {
         final UserInfo user1 = createUser("User 1", /* flags= */ 0);
         synchronized (mUserRemoveLock) {
-            assertThat(mUserManager.removeUserOrSetEphemeral(user1.id)).isEqualTo(
-                    UserManager.REMOVE_RESULT_REMOVED);
+            assertThat(mUserManager.removeUserOrSetEphemeral(user1.id,
+                    /* evenWhenDisallowed= */ false)).isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
             waitForUserRemovalLocked(user1.id);
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
index 0b44c59..b11bb85 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
@@ -366,36 +366,19 @@
             actualPackages.add(p.packageName);
         }
 
-        // Add auto-generated RRO package to expectedPackages since they are not (supposed to be)
-        // in the allowlist but they should be installed.
+        // Add static overlays to expectedPackages since they are not (supposed to be)
+        // in the allowlist but they should be installed if their target is.
         for (PackageInfo p : packageInfos) {
-            if (p.isOverlayPackage()
-                        && UserSystemPackageInstaller.hasAutoGeneratedRROSuffix(p.packageName)
-                        && expectedPackages.contains(p.overlayTarget)) {
+            if (p.isStaticOverlayPackage() && expectedPackages.contains(p.overlayTarget)) {
                 expectedPackages.add(p.packageName);
             }
         }
         checkPackageDifferences(expectedPackages, actualPackages);
     }
 
-    @Test
-    public void testAutoGeneratedRROMatchesSuffix() {
-        final List<PackageInfo> packageInfos = mContext.getPackageManager()
-                .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
-
-        Log.v(TAG, "Found total packages: " + packageInfos.size());
-
-        for (PackageInfo p : packageInfos) {
-            if (p.packageName.contains(".auto_generated_rro_")) {
-                assertTrue("Auto-generated RRO package name does not match the suffix: "
-                        + p.packageName,
-                        UserSystemPackageInstaller.hasAutoGeneratedRROSuffix(p.packageName));
-            }
-        }
-    }
-
     /**
-     * Test that overlay package not in allowlist should be installed for all user at Explicit mode.
+     * Test that static overlay package not in allowlist should be installed for all users
+     * based on their targets, in Explicit mode.
      */
     @Test
     public void testInstallOverlayPackagesExplicitMode() {
@@ -408,19 +391,32 @@
         final String packageName2 = "nonWhitelistedPkg";
         final String overlayName1 = String.format("%s.auto_generated_rro_product__", packageName1);
         final String overlayName2 = String.format("%s.auto_generated_rro_product__", packageName2);
+        final String overlayName3 = String.format("%s.non_static_overlay", packageName1);
 
+        // Static overlay for allowlisted package1 -> should be installed, like package1
         final AndroidPackage overlayPackage1 = ((ParsedPackage) PackageImpl.forTesting(overlayName1)
                 .setOverlay(true)
+                .setOverlayIsStatic(true)
                 .setOverlayTarget(packageName1)
                 .hideAsParsed())
                 .hideAsFinal();
 
+        // Static overlay for non-allowlisted package2 -> should not be installed, like package2
         final AndroidPackage overlayPackage2 = ((ParsedPackage) PackageImpl.forTesting(overlayName2)
                 .setOverlay(true)
+                .setOverlayIsStatic(true)
                 .setOverlayTarget(packageName2)
                 .hideAsParsed())
                 .hideAsFinal();
 
+        // Non-static overlay for package1 -> not explicitly allowlisted, so shouldn't be installed
+        final AndroidPackage overlayPackage3 = ((ParsedPackage) PackageImpl.forTesting(overlayName3)
+                .setOverlay(true)
+                .setOverlayIsStatic(false) // non-static
+                .setOverlayTarget(packageName1)
+                .hideAsParsed())
+                .hideAsFinal();
+
         final ArrayMap<String, Long> userTypeWhitelist = new ArrayMap<>();
         userTypeWhitelist.put(packageName1, maskOfType);
 
@@ -428,10 +424,12 @@
         userWhitelist.add(packageName1);
 
         boolean implicit = false;
-        assertTrue("Overlay for package1 should be installed", UserSystemPackageInstaller
+        assertTrue("Should install static overlay for package1", UserSystemPackageInstaller
                 .shouldInstallPackage(overlayPackage1, userTypeWhitelist, userWhitelist, implicit));
-        assertFalse("Overlay for package2 should not be installed", UserSystemPackageInstaller
+        assertFalse("Should not install static overlay for package2", UserSystemPackageInstaller
                 .shouldInstallPackage(overlayPackage2, userTypeWhitelist, userWhitelist, implicit));
+        assertFalse("Should not install regular overlay for package1", UserSystemPackageInstaller
+                .shouldInstallPackage(overlayPackage3, userTypeWhitelist, userWhitelist, implicit));
     }
 
     /** Asserts that actual is a subset of expected. */
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 f07197c..7f35511 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -77,7 +77,6 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
-import com.android.server.display.DisplayGroup;
 import com.android.server.lights.LightsManager;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.power.PowerManagerService.BatteryReceiver;
@@ -98,12 +97,9 @@
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Tests for {@link com.android.server.power.PowerManagerService}.
@@ -182,8 +178,7 @@
                 .thenReturn(mPowerSaveState);
         when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(false);
         when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
-        when(mDisplayManagerInternalMock.requestPowerState(anyInt(), any(),
-                anyBoolean())).thenReturn(true);
+        when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
         when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
 
@@ -404,33 +399,30 @@
     @Test
     public void testGetDesiredScreenPolicy_WithVR() throws Exception {
         createService();
-        mService.systemReady(null);
         // Brighten up the screen
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_BRIGHT);
 
         // Move to VR
         mService.setVrModeEnabled(true);
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_VR);
 
         // Then take a nap
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+                0);
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_OFF);
 
         // Wake up to VR
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_VR);
 
         // And back to normal
         mService.setVrModeEnabled(false);
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_BRIGHT);
     }
 
@@ -681,9 +673,8 @@
     }
 
     @Test
-    public void testForceSuspend_forceSuspendFailurePropagated() throws Exception {
+    public void testForceSuspend_forceSuspendFailurePropogated() {
         createService();
-        startSystem();
         when(mNativeWrapperMock.nativeForceSuspend()).thenReturn(false);
         assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();
     }
@@ -847,7 +838,7 @@
         createService();
         startSystem();
 
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_BRIGHT);
     }
 
@@ -866,8 +857,11 @@
     public void testQuiescentBoot_DesiredScreenPolicyShouldBeOff() throws Exception {
         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1");
         createService();
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
+                DisplayPowerRequest.POLICY_OFF);
+
         startSystem();
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_OFF);
     }
 
@@ -877,7 +871,7 @@
         createService();
         startSystem();
         forceAwake();
-        assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
+        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                 DisplayPowerRequest.POLICY_BRIGHT);
     }
 
@@ -1149,85 +1143,4 @@
         assertFalse(
                 mService.getBinderServiceInstance().setPowerModeChecked(Mode.INTERACTIVE, false));
     }
-
-    @Test
-    public void testMultiDisplay_wakefulnessUpdates() throws Exception {
-        final int nonDefaultDisplayGroupId = DisplayGroup.DEFAULT + 1;
-        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
-                new AtomicReference<>();
-        doAnswer((Answer<Void>) invocation -> {
-            listener.set(invocation.getArgument(0));
-            return null;
-        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
-
-        createService();
-        startSystem();
-        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
-
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-
-        mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
-                null, null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-    }
-
-    @Test
-    public void testMultiDisplay_addDisplayGroup_preservesWakefulness() throws Exception {
-        final int nonDefaultDisplayGroupId = DisplayGroup.DEFAULT + 1;
-        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
-                new AtomicReference<>();
-        doAnswer((Answer<Void>) invocation -> {
-            listener.set(invocation.getArgument(0));
-            return null;
-        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
-
-        createService();
-        startSystem();
-
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-
-        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
-
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-    }
-
-    @Test
-    public void testMultiDisplay_removeDisplayGroup_updatesWakefulness() throws Exception {
-        final int nonDefaultDisplayGroupId = DisplayGroup.DEFAULT + 1;
-        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
-                new AtomicReference<>();
-        doAnswer((Answer<Void>) invocation -> {
-            listener.set(invocation.getArgument(0));
-            return null;
-        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
-
-        createService();
-        startSystem();
-        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
-
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-
-        listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-
-        mService.setWakefulnessLocked(DisplayGroup.DEFAULT, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null,
-                null);
-        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 6ca9de3..b18bf27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
+import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
@@ -1901,6 +1902,75 @@
                 true /* shouldUpdate */, false /* activityChange */);
     }
 
+    @Test
+    public void testSupportsSplitScreenWindowingMode() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+                .build();
+
+        // Non-resizable
+        mAtm.mForceResizableActivities = false;
+        mAtm.mSupportsNonResizableMultiWindow = false;
+        assertFalse(activity.supportsSplitScreenWindowingMode());
+
+        // Force resizable
+        mAtm.mForceResizableActivities = true;
+        mAtm.mSupportsNonResizableMultiWindow = false;
+        assertTrue(activity.supportsSplitScreenWindowingMode());
+
+        // Allow non-resizable
+        mAtm.mForceResizableActivities = false;
+        mAtm.mSupportsNonResizableMultiWindow = true;
+        assertTrue(activity.supportsSplitScreenWindowingMode());
+    }
+
+    @Test
+    public void testSupportsFreeform() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+                .build();
+
+        // Non-resizable
+        mAtm.mForceResizableActivities = false;
+        mAtm.mSizeCompatFreeform = false;
+        assertFalse(activity.supportsFreeform());
+
+        // Force resizable
+        mAtm.mForceResizableActivities = true;
+        mAtm.mSizeCompatFreeform = false;
+        assertTrue(activity.supportsFreeform());
+
+        // Allow non-resizable
+        mAtm.mForceResizableActivities = false;
+        mAtm.mSizeCompatFreeform = true;
+        assertTrue(activity.supportsFreeform());
+    }
+
+    @Test
+    public void testSupportsPictureInPicture() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+                .setActivityFlags(FLAG_SUPPORTS_PICTURE_IN_PICTURE)
+                .build();
+
+        // Device not supports PIP
+        mAtm.mSupportsPictureInPicture = false;
+        assertFalse(activity.supportsPictureInPicture());
+
+        // Device and app support PIP
+        mAtm.mSupportsPictureInPicture = true;
+        assertTrue(activity.supportsPictureInPicture());
+
+        // Activity not supports PIP
+        activity.info.flags &= ~FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+        assertFalse(activity.supportsPictureInPicture());
+    }
+
     private void verifyProcessInfoUpdate(ActivityRecord activity, ActivityState state,
             boolean shouldUpdate, boolean activityChange) {
         reset(activity.app);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
index 4e1b351..0dd8d23 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
@@ -132,6 +133,21 @@
     }
 
     @Test
+    public void testSupportsNonResizableMultiWindow() {
+        try (BoolSettingsSession supportsNonResizableMultiWindowSession = new
+                BoolSettingsSession(DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW)) {
+            final boolean supportsNonResizableMultiWindow =
+                    !supportsNonResizableMultiWindowSession.getSetting();
+            final Uri supportsNonResizableMultiWindowUri = supportsNonResizableMultiWindowSession
+                    .setSetting(supportsNonResizableMultiWindow);
+            mWm.mSettingsObserver.onChange(false, supportsNonResizableMultiWindowUri);
+
+            assertEquals(mWm.mAtmService.mSupportsNonResizableMultiWindow,
+                    supportsNonResizableMultiWindow);
+        }
+    }
+
+    @Test
     public void testChangeBaseDisplaySettingsPath() {
         try (StringSettingsSession baseDisplaySettingsPathSession = new
                 StringSettingsSession(DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH)) {
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 d8be2c1..37983b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1216,6 +1216,34 @@
         return result;
     }
 
+    @Test
+    public void testReparentNonResizableTaskToSplitScreen() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+                .build();
+        final Task rootTask = activity.getRootTask();
+        rootTask.setResizeMode(activity.info.resizeMode);
+        final Task splitPrimaryRootTask = mWm.mAtmService.mTaskOrganizerController.createRootTask(
+                mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.reparent(rootTask.mRemoteToken.toWindowContainerToken(),
+                splitPrimaryRootTask.mRemoteToken.toWindowContainerToken(), true /* onTop */);
+
+        // Can't reparent non-resizable to split screen
+        mAtm.mSupportsNonResizableMultiWindow = false;
+        mAtm.mWindowOrganizerController.applyTransaction(wct);
+
+        assertEquals(rootTask, activity.getRootTask());
+
+        // Allow reparent non-resizable to split screen
+        mAtm.mSupportsNonResizableMultiWindow = true;
+        mAtm.mWindowOrganizerController.applyTransaction(wct);
+
+        assertEquals(splitPrimaryRootTask, activity.getRootTask());
+    }
+
     /**
      * Verifies that task vanished is called for a specific task.
      */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 93414f4..4f44a06 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2853,6 +2853,30 @@
     public static final String IMSI_KEY_DOWNLOAD_URL_STRING = "imsi_key_download_url_string";
 
     /**
+     * String representation of a carrier's public key used for IMSI encryption for ePDG. If this
+     * is provided, the device will use it as a fallback when no key exists on device, but the key
+     * download will still initiate.
+     * Example string:
+     *         "-----BEGIN CERTIFICATE-----\nabcde12345abcde12345abcde12345abcde1234
+     * 5abcde12345abcde12345\nabcde12345abcde12345abcde12345abcde12345a\n-----END CERTIFICATE-----"
+     * @hide
+     */
+    public static final String IMSI_CARRIER_PUBLIC_KEY_EPDG_STRING =
+            "imsi_carrier_public_key_epdg_string";
+
+    /**
+     * String representation of a carrier's public key used for IMSI encryption for WLAN. If this
+     * is provided, the device will use it as a fallback when no key exists on device, but the key
+     * download will still initiate.
+     * Example string:
+     *         "-----BEGIN CERTIFICATE-----\nabcde12345abcde12345abcde12345abcde1234
+     * 5abcde12345abcde12345\nabcde12345abcde12345abcde12345abcde12345a\n-----END CERTIFICATE-----"
+     * @hide
+     */
+    public static final String IMSI_CARRIER_PUBLIC_KEY_WLAN_STRING =
+            "imsi_carrier_public_key_wlan_string";
+
+    /**
      * Identifies if the key is available for WLAN or EPDG or both. The value is a bitmask.
      * 0 indicates that neither EPDG or WLAN is enabled.
      * 1 indicates that key type TelephonyManager#KEY_TYPE_EPDG is enabled.
@@ -5056,6 +5080,8 @@
         sDefaults.putBoolean(KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
         sDefaults.putInt(IMSI_KEY_AVAILABILITY_INT, 0);
         sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null);
+        sDefaults.putString(IMSI_CARRIER_PUBLIC_KEY_EPDG_STRING, null);
+        sDefaults.putString(IMSI_CARRIER_PUBLIC_KEY_WLAN_STRING, null);
         sDefaults.putBoolean(KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
                 false);
         sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java
index 75a79d6..4978692 100644
--- a/telephony/java/android/telephony/ImsiEncryptionInfo.java
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java
@@ -163,8 +163,8 @@
     public String toString(){
         return "[ImsiEncryptionInfo "
                 + "mcc=" + mcc
-                + "mnc=" + mnc
-                + "publicKey=" + publicKey
+                + " mnc=" + mnc
+                + " publicKey=" + publicKey
                 + ", keyIdentifier=" + keyIdentifier
                 + ", keyType=" + keyType
                 + ", expirationTime=" + expirationTime
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 250d9e8..3b4cf75 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -121,7 +121,7 @@
     public static final int BEARER_CAPABILITY_NOT_AUTHORIZED                 = 57;
     /** The requested bearer capability is not available at this time. */
     public static final int BEARER_NOT_AVAIL                                 = 58;
-    /** The service option is not availble at this time. */
+    /** The service option is not available at this time. */
     public static final int SERVICE_OPTION_NOT_AVAILABLE                     = 63;
     /** The equipment sending this cause does not support the bearer capability requested. */
     public static final int BEARER_SERVICE_NOT_IMPLEMENTED                   = 65;
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.aidl b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.aidl
new file mode 100644
index 0000000..da31f98
--- /dev/null
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.data;
+
+ parcelable EpsBearerQosSessionAttributes;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
new file mode 100644
index 0000000..041edc0
--- /dev/null
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
@@ -0,0 +1,234 @@
+/*
+ * 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.telephony.data;
+
+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.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Provides Qos attributes of an EPS bearer.
+ *
+ * {@hide}
+ */
+@SystemApi
+public final class EpsBearerQosSessionAttributes implements Parcelable, QosSessionAttributes {
+    private static final String TAG = EpsBearerQosSessionAttributes.class.getSimpleName();
+    private final int mQci;
+    private final long mMaxUplinkBitRate;
+    private final long mMaxDownlinkBitRate;
+    private final long mGuaranteedUplinkBitRate;
+    private final long mGuaranteedDownlinkBitRate;
+    @NonNull private final List<InetSocketAddress> mRemoteAddresses;
+
+    /**
+     * Quality of Service Class Identifier (QCI), see 3GPP TS 23.203 and 29.212.
+     * 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 qci of the session
+     */
+    public int getQci() {
+        return mQci;
+    }
+
+    /**
+     * Minimum bit rate in kbps that is guaranteed to be provided by the network on the uplink.
+     *
+     * see 3GPP TS 23.107 section 6.4.3.1
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the guaranteed bit rate in kbps
+     */
+    public long getGuaranteedUplinkBitRate() {
+        return mGuaranteedUplinkBitRate;
+    }
+
+    /**
+     * Minimum bit rate in kbps that is guaranteed to be provided by the network on the downlink.
+     *
+     * see 3GPP TS 23.107 section 6.4.3.1
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the guaranteed bit rate in kbps
+     */
+    public long getGuaranteedDownlinkBitRate() {
+        return mGuaranteedDownlinkBitRate;
+    }
+
+    /**
+     * The maximum kbps that the network will accept.
+     *
+     * see 3GPP TS 23.107 section 6.4.3.1
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the max uplink bit rate in kbps
+     */
+    public long getMaxUplinkBitRate() {
+        return mMaxUplinkBitRate;
+    }
+
+    /**
+     * The maximum kbps that the network can provide.
+     *
+     * see 3GPP TS 23.107 section 6.4.3.1
+     *
+     * Note: The Qos Session may be shared with OTHER applications besides yours.
+     *
+     * @return the max downlink bit rate in kbps
+     */
+    public long getMaxDownlinkBitRate() {
+        return mMaxDownlinkBitRate;
+    }
+
+    /**
+     * 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 qci quality class indicator
+     * @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 remoteAddresses the remote addresses that the uplink bit rates apply to
+     *
+     * @hide
+     */
+    public EpsBearerQosSessionAttributes(final int qci,
+            final long maxDownlinkBitRate, final long maxUplinkBitRate,
+            final long guaranteedDownlinkBitRate, final long guaranteedUplinkBitRate,
+            @NonNull final List<InetSocketAddress> remoteAddresses) {
+        Objects.requireNonNull(remoteAddresses, "remoteAddress must be non-null");
+        mQci = qci;
+        mMaxDownlinkBitRate = maxDownlinkBitRate;
+        mMaxUplinkBitRate = maxUplinkBitRate;
+        mGuaranteedDownlinkBitRate = guaranteedDownlinkBitRate;
+        mGuaranteedUplinkBitRate = guaranteedUplinkBitRate;
+
+        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 EpsBearerQosSessionAttributes(@NonNull final Parcel in) {
+        mQci = in.readInt();
+        mMaxDownlinkBitRate = in.readLong();
+        mMaxUplinkBitRate = in.readLong();
+        mGuaranteedDownlinkBitRate = in.readLong();
+        mGuaranteedUplinkBitRate = 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 we filter out null values in the ..ctor
+                Log.e(TAG, "unable to unparcel remote address at index: " + i, e);
+            }
+        }
+        mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
+    }
+
+    /**
+     * Creates attributes based off of a parcel
+     * @param in the parcel
+     * @return the attributes
+     */
+    @NonNull
+    public static EpsBearerQosSessionAttributes create(@NonNull final Parcel in) {
+        return new EpsBearerQosSessionAttributes(in);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull final Parcel dest, final int flags) {
+        dest.writeInt(mQci);
+        dest.writeLong(mMaxDownlinkBitRate);
+        dest.writeLong(mMaxUplinkBitRate);
+        dest.writeLong(mGuaranteedDownlinkBitRate);
+        dest.writeLong(mGuaranteedUplinkBitRate);
+
+        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<EpsBearerQosSessionAttributes> CREATOR =
+            new Creator<EpsBearerQosSessionAttributes>() {
+        @NonNull
+        @Override
+        public EpsBearerQosSessionAttributes createFromParcel(@NonNull final Parcel in) {
+            return new EpsBearerQosSessionAttributes(in);
+        }
+
+        @NonNull
+        @Override
+        public EpsBearerQosSessionAttributes[] newArray(final int size) {
+            return new EpsBearerQosSessionAttributes[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index a5a8958..dda021e 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -893,7 +893,6 @@
     /**
      * Call failed because of network congestion, resource is not available,
      * or no circuit or channel available, etc.
-     * @hide
      */
     public static final int CODE_NETWORK_CONGESTION = 1624;
 
@@ -1276,6 +1275,7 @@
         sImsCodeMap.put(CODE_REJECT_VT_AVPF_NOT_ALLOWED, "CODE_REJECT_VT_AVPF_NOT_ALLOWED");
         sImsCodeMap.put(CODE_REJECT_ONGOING_ENCRYPTED_CALL, "CODE_REJECT_ONGOING_ENCRYPTED_CALL");
         sImsCodeMap.put(CODE_REJECT_ONGOING_CS_CALL, "CODE_REJECT_ONGOING_CS_CALL");
+        sImsCodeMap.put(CODE_NETWORK_CONGESTION, "CODE_NETWORK_CONGESTION");
         sImsCodeMap.put(CODE_RETRY_ON_IMS_WITHOUT_RTT, "CODE_RETRY_ON_IMS_WITHOUT_RTT");
         sImsCodeMap.put(CODE_OEM_CAUSE_1, "CODE_OEM_CAUSE_1");
         sImsCodeMap.put(CODE_OEM_CAUSE_2, "CODE_OEM_CAUSE_2");
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 79d746a..531dd7c 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -9,7 +9,6 @@
     method public int getInstallReason(String, android.os.UserHandle);
     method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
     method public String[] getNamesForUids(int[]);
-    method public String getPermissionControllerPackageName();
     method @NonNull public String getServicesSystemSharedLibraryPackageName();
     method @NonNull public String getSharedSystemSharedLibraryPackageName();
   }
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 3d4dc4d..dc9e587 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -31,6 +31,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
@@ -40,6 +41,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkProvider;
 import android.net.NetworkSpecifier;
+import android.net.QosFilter;
 import android.net.SocketKeepalive;
 import android.net.UidRange;
 import android.os.ConditionVariable;
@@ -47,10 +49,12 @@
 import android.os.Message;
 import android.util.Log;
 
+import com.android.net.module.util.ArrayTrackRecord;
 import com.android.server.connectivity.ConnectivityConstants;
 import com.android.testutils.HandlerUtils;
 import com.android.testutils.TestableNetworkCallback;
 
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -71,6 +75,8 @@
     // start/stop. Useful when simulate KeepaliveTracker is waiting for response from modem.
     private long mKeepaliveResponseDelay = 0L;
     private Integer mExpectedKeepaliveSlot = null;
+    private final ArrayTrackRecord<CallbackType>.ReadHead mCallbackHistory =
+            new ArrayTrackRecord<CallbackType>().newReadHead();
 
     public NetworkAgentWrapper(int transport, LinkProperties linkProperties,
             NetworkCapabilities ncTemplate, Context context) throws Exception {
@@ -157,6 +163,20 @@
         }
 
         @Override
+        public void onQosCallbackRegistered(final int qosCallbackId,
+                final @NonNull QosFilter filter) {
+            Log.i(mWrapper.mLogTag, "onQosCallbackRegistered");
+            mWrapper.mCallbackHistory.add(
+                    new CallbackType.OnQosCallbackRegister(qosCallbackId, filter));
+        }
+
+        @Override
+        public void onQosCallbackUnregistered(final int qosCallbackId) {
+            Log.i(mWrapper.mLogTag, "onQosCallbackUnregistered");
+            mWrapper.mCallbackHistory.add(new CallbackType.OnQosCallbackUnregister(qosCallbackId));
+        }
+
+        @Override
         protected void preventAutomaticReconnect() {
             mWrapper.mPreventReconnectReceived.open();
         }
@@ -279,7 +299,60 @@
         return mNetworkCapabilities;
     }
 
+    public @NonNull ArrayTrackRecord<CallbackType>.ReadHead getCallbackHistory() {
+        return mCallbackHistory;
+    }
+
     public void waitForIdle(long timeoutMs) {
         HandlerUtils.waitForIdle(mHandlerThread, timeoutMs);
     }
+
+    abstract static class CallbackType {
+        final int mQosCallbackId;
+
+        protected CallbackType(final int qosCallbackId) {
+            mQosCallbackId = qosCallbackId;
+        }
+
+        static class OnQosCallbackRegister extends CallbackType {
+            final QosFilter mFilter;
+            OnQosCallbackRegister(final int qosCallbackId, final QosFilter filter) {
+                super(qosCallbackId);
+                mFilter = filter;
+            }
+
+            @Override
+            public boolean equals(final Object o) {
+                if (this == o) return true;
+                if (o == null || getClass() != o.getClass()) return false;
+                final OnQosCallbackRegister that = (OnQosCallbackRegister) o;
+                return mQosCallbackId == that.mQosCallbackId
+                        && Objects.equals(mFilter, that.mFilter);
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mQosCallbackId, mFilter);
+            }
+        }
+
+        static class OnQosCallbackUnregister extends CallbackType {
+            OnQosCallbackUnregister(final int qosCallbackId) {
+                super(qosCallbackId);
+            }
+
+            @Override
+            public boolean equals(final Object o) {
+                if (this == o) return true;
+                if (o == null || getClass() != o.getClass()) return false;
+                final OnQosCallbackUnregister that = (OnQosCallbackUnregister) o;
+                return mQosCallbackId == that.mQosCallbackId;
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mQosCallbackId);
+            }
+        }
+    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 4630269..c5e6c35 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -167,6 +167,7 @@
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkStatsService;
+import android.net.IQosCallback;
 import android.net.InetAddresses;
 import android.net.InterfaceConfigurationParcel;
 import android.net.IpPrefix;
@@ -190,6 +191,9 @@
 import android.net.NetworkState;
 import android.net.NetworkTestResultParcelable;
 import android.net.ProxyInfo;
+import android.net.QosCallbackException;
+import android.net.QosFilter;
+import android.net.QosSession;
 import android.net.ResolverParamsParcel;
 import android.net.RouteInfo;
 import android.net.RouteInfoParcel;
@@ -218,6 +222,7 @@
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -226,10 +231,12 @@
 import android.security.KeyStore;
 import android.system.Os;
 import android.telephony.TelephonyManager;
+import android.telephony.data.EpsBearerQosSessionAttributes;
 import android.test.mock.MockContentResolver;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 
 import androidx.test.InstrumentationRegistry;
@@ -251,6 +258,7 @@
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 import com.android.server.connectivity.ProxyTracker;
+import com.android.server.connectivity.QosCallbackTracker;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -368,6 +376,8 @@
     private WrappedMultinetworkPolicyTracker mPolicyTracker;
     private HandlerThread mAlarmManagerThread;
     private TestNetIdManager mNetIdManager;
+    private QosCallbackMockHelper mQosCallbackMockHelper;
+    private QosCallbackTracker mQosCallbackTracker;
 
     @Mock DeviceIdleInternal mDeviceIdleInternal;
     @Mock INetworkManagementService mNetworkManagementService;
@@ -1395,6 +1405,7 @@
         mService.systemReadyInternal();
         mockVpn(Process.myUid());
         mCm.bindProcessToNetwork(null);
+        mQosCallbackTracker = mock(QosCallbackTracker.class);
 
         // Ensure that the default setting for Captive Portals is used for most tests
         setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
@@ -1470,6 +1481,11 @@
             mEthernetNetworkAgent.disconnect();
             mEthernetNetworkAgent = null;
         }
+
+        if (mQosCallbackMockHelper != null) {
+            mQosCallbackMockHelper.tearDown();
+            mQosCallbackMockHelper = null;
+        }
         mMockVpn.disconnect();
         waitForIdle();
 
@@ -4379,7 +4395,7 @@
     }
 
     private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception {
-        // Ensure the network is disconnected before we do anything.
+        // Ensure the network is disconnected before anything else occurs
         if (mWiFiNetworkAgent != null) {
             assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
         }
@@ -8512,7 +8528,7 @@
                 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
         return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
                 nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, null,
-                0, INVALID_UID);
+                0, INVALID_UID, mQosCallbackTracker);
     }
 
     @Test
@@ -8890,7 +8906,7 @@
 
     @Test
     public void testInvalidRequestTypes() {
-        final int[] invalidReqTypeInts = new int[] {-1, NetworkRequest.Type.NONE.ordinal(),
+        final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(),
                 NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length};
         final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
 
@@ -8903,4 +8919,151 @@
             );
         }
     }
+
+    private class QosCallbackMockHelper {
+        @NonNull public final QosFilter mFilter;
+        @NonNull public final IQosCallback mCallback;
+        @NonNull public final TestNetworkAgentWrapper mAgentWrapper;
+        @NonNull private final List<IQosCallback> mCallbacks = new ArrayList();
+
+        QosCallbackMockHelper() throws Exception {
+            Log.d(TAG, "QosCallbackMockHelper: ");
+            mFilter = mock(QosFilter.class);
+
+            // Ensure the network is disconnected before anything else occurs
+            assertNull(mCellNetworkAgent);
+
+            mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+            mCellNetworkAgent.connect(true);
+
+            verifyActiveNetwork(TRANSPORT_CELLULAR);
+            waitForIdle();
+            final Network network = mCellNetworkAgent.getNetwork();
+
+            final Pair<IQosCallback, IBinder> pair = createQosCallback();
+            mCallback = pair.first;
+
+            when(mFilter.getNetwork()).thenReturn(network);
+            when(mFilter.validate()).thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
+            mAgentWrapper = mCellNetworkAgent;
+        }
+
+        void registerQosCallback(@NonNull final QosFilter filter,
+                @NonNull final IQosCallback callback) {
+            mCallbacks.add(callback);
+            final NetworkAgentInfo nai =
+                    mService.getNetworkAgentInfoForNetwork(filter.getNetwork());
+            mService.registerQosCallbackInternal(filter, callback, nai);
+        }
+
+        void tearDown() {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                mService.unregisterQosCallback(mCallbacks.get(i));
+            }
+        }
+    }
+
+    private Pair<IQosCallback, IBinder> createQosCallback() {
+        final IQosCallback callback = mock(IQosCallback.class);
+        final IBinder binder = mock(Binder.class);
+        when(callback.asBinder()).thenReturn(binder);
+        when(binder.isBinderAlive()).thenReturn(true);
+        return new Pair<>(callback, binder);
+    }
+
+
+    @Test
+    public void testQosCallbackRegistration() throws Exception {
+        mQosCallbackMockHelper = new QosCallbackMockHelper();
+        final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper;
+
+        when(mQosCallbackMockHelper.mFilter.validate())
+                .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
+        mQosCallbackMockHelper.registerQosCallback(
+                mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback);
+
+        final NetworkAgentWrapper.CallbackType.OnQosCallbackRegister cbRegister1 =
+                (NetworkAgentWrapper.CallbackType.OnQosCallbackRegister)
+                        wrapper.getCallbackHistory().poll(1000, x -> true);
+        assertNotNull(cbRegister1);
+
+        final int registerCallbackId = cbRegister1.mQosCallbackId;
+        mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback);
+        final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister;
+        cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister)
+                wrapper.getCallbackHistory().poll(1000, x -> true);
+        assertNotNull(cbUnregister);
+        assertEquals(registerCallbackId, cbUnregister.mQosCallbackId);
+        assertNull(wrapper.getCallbackHistory().poll(200, x -> true));
+    }
+
+    @Test
+    public void testQosCallbackNoRegistrationOnValidationError() throws Exception {
+        mQosCallbackMockHelper = new QosCallbackMockHelper();
+
+        when(mQosCallbackMockHelper.mFilter.validate())
+                .thenReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
+        mQosCallbackMockHelper.registerQosCallback(
+                mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback);
+        waitForIdle();
+        verify(mQosCallbackMockHelper.mCallback)
+                .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED));
+    }
+
+    @Test
+    public void testQosCallbackAvailableAndLost() 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 EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes(
+                1, 2, 3, 4, 5, new ArrayList<>());
+        mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+                .sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
+        waitForIdle();
+
+        verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session ->
+                session.getSessionId() == sessionId
+                        && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes));
+
+        mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent()
+                .sendQosSessionLost(qosCallbackId, sessionId);
+        waitForIdle();
+        verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session ->
+                session.getSessionId() == sessionId
+                        && session.getSessionType() == QosSession.TYPE_EPS_BEARER));
+    }
+
+    @Test
+    public void testQosCallbackTooManyRequests() throws Exception {
+        mQosCallbackMockHelper = new QosCallbackMockHelper();
+
+        when(mQosCallbackMockHelper.mFilter.validate())
+                .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE);
+        for (int i = 0; i < 100; i++) {
+            final Pair<IQosCallback, IBinder> pair = createQosCallback();
+
+            try {
+                mQosCallbackMockHelper.registerQosCallback(
+                        mQosCallbackMockHelper.mFilter, pair.first);
+            } catch (ServiceSpecificException e) {
+                assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS);
+                if (i < 50) {
+                    fail("TOO_MANY_REQUESTS thrown too early, the count is " + i);
+                }
+
+                // As long as there is at least 50 requests, it is safe to assume it works.
+                // Note: The count isn't being tested precisely against 100 because the counter
+                // is shared with request network.
+                return;
+            }
+        }
+        fail("TOO_MANY_REQUESTS never thrown");
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 4d151af..52cb836 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -78,6 +78,7 @@
     @Mock Context mCtx;
     @Mock NetworkNotificationManager mNotifier;
     @Mock Resources mResources;
+    @Mock QosCallbackTracker mQosCallbackTracker;
 
     @Before
     public void setUp() {
@@ -358,7 +359,7 @@
         NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
                 new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
                 mConnService, mNetd, mDnsResolver, mNMS, NetworkProvider.ID_NONE,
-                Binder.getCallingUid());
+                Binder.getCallingUid(), mQosCallbackTracker);
         nai.everValidated = true;
         return nai;
     }
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 696110f..29cfdb6f 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -23,10 +23,15 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -35,8 +40,10 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
 import android.net.vcn.VcnConfigTest;
+import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.os.Process;
@@ -126,6 +133,10 @@
 
     private final VcnManagementService mVcnMgmtSvc;
 
+    private final IVcnUnderlyingNetworkPolicyListener mMockPolicyListener =
+            mock(IVcnUnderlyingNetworkPolicyListener.class);
+    private final IBinder mMockIBinder = mock(IBinder.class);
+
     public VcnManagementServiceTest() throws Exception {
         setupSystemService(mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class);
         setupSystemService(mTelMgr, Context.TELEPHONY_SERVICE, TelephonyManager.class);
@@ -169,6 +180,8 @@
         setupMockedCarrierPrivilege(true);
         mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps);
 
+        doReturn(mMockIBinder).when(mMockPolicyListener).asBinder();
+
         // Make sure the profiles are loaded.
         mTestLooper.dispatchAll();
     }
@@ -438,4 +451,40 @@
         mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
         verify(vcnInstance).teardownAsynchronously();
     }
+
+    @Test
+    public void testAddVcnUnderlyingNetworkPolicyListener() throws Exception {
+        doNothing()
+                .when(mMockContext)
+                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+
+        verify(mMockIBinder).linkToDeath(any(), anyInt());
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
+        doThrow(new SecurityException())
+                .when(mMockContext)
+                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+    }
+
+    @Test
+    public void testRemoveVcnUnderlyingNetworkPolicyListener() {
+        // verify listener added
+        doNothing()
+                .when(mMockContext)
+                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
+        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+
+        mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+    }
+
+    @Test
+    public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
+        mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+    }
 }