Merge "Increase RESTRICTED timeout to 45 days." into sc-dev
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 4378a98..c1fcd6c 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -120,7 +120,7 @@
     /** Builder for {@link AppSearchSchema objects}. */
     public static final class Builder {
         private final String mSchemaType;
-        private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
+        private ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
         private final Set<String> mPropertyNames = new ArraySet<>();
         private boolean mBuilt = false;
 
@@ -133,8 +133,8 @@
         /** Adds a property to the given type. */
         @NonNull
         public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(propertyConfig);
+            resetIfBuilt();
             String name = propertyConfig.getName();
             if (!mPropertyNames.add(name)) {
                 throw new IllegalSchemaException("Property defined more than once: " + name);
@@ -143,20 +143,22 @@
             return this;
         }
 
-        /**
-         * Constructs a new {@link AppSearchSchema} from the contents of this builder.
-         *
-         * <p>After calling this method, the builder must no longer be used.
-         */
+        /** Constructs a new {@link AppSearchSchema} from the contents of this builder. */
         @NonNull
         public AppSearchSchema build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Bundle bundle = new Bundle();
             bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mSchemaType);
             bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
             mBuilt = true;
             return new AppSearchSchema(bundle);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mPropertyBundles = new ArrayList<>(mPropertyBundles);
+                mBuilt = false;
+            }
+        }
     }
 
     /**
@@ -251,6 +253,7 @@
         }
 
         @Override
+        @NonNull
         public String toString() {
             return mBundle.toString();
         }
@@ -410,16 +413,14 @@
 
         /** Builder for {@link StringPropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            private @IndexingType int mIndexingType = INDEXING_TYPE_NONE;
+            private @TokenizerType int mTokenizerType = TOKENIZER_TYPE_NONE;
 
             /** Creates a new {@link StringPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
-                mBundle.putInt(INDEXING_TYPE_FIELD, INDEXING_TYPE_NONE);
-                mBundle.putInt(TOKENIZER_TYPE_FIELD, TOKENIZER_TYPE_NONE);
+                mPropertyName = Objects.requireNonNull(propertyName);
             }
 
             /**
@@ -431,10 +432,9 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public StringPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
@@ -446,10 +446,9 @@
              */
             @NonNull
             public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
-                mBundle.putInt(INDEXING_TYPE_FIELD, indexingType);
+                mIndexingType = indexingType;
                 return this;
             }
 
@@ -466,25 +465,22 @@
              */
             @NonNull
             public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
-                mBundle.putInt(TOKENIZER_TYPE_FIELD, tokenizerType);
+                mTokenizerType = tokenizerType;
                 return this;
             }
 
-            /**
-             * Constructs a new {@link StringPropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link StringPropertyConfig} from the contents of this builder. */
             @NonNull
             public StringPropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new StringPropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                bundle.putInt(INDEXING_TYPE_FIELD, mIndexingType);
+                bundle.putInt(TOKENIZER_TYPE_FIELD, mTokenizerType);
+                return new StringPropertyConfig(bundle);
             }
         }
     }
@@ -497,14 +493,12 @@
 
         /** Builder for {@link Int64PropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link Int64PropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+                mPropertyName = Objects.requireNonNull(propertyName);
             }
 
             /**
@@ -516,25 +510,20 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public Int64PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
-            /**
-             * Constructs a new {@link Int64PropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link Int64PropertyConfig} from the contents of this builder. */
             @NonNull
             public Int64PropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new Int64PropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                return new Int64PropertyConfig(bundle);
             }
         }
     }
@@ -547,14 +536,12 @@
 
         /** Builder for {@link DoublePropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link DoublePropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+                mPropertyName = Objects.requireNonNull(propertyName);
             }
 
             /**
@@ -566,25 +553,20 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public DoublePropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
-            /**
-             * Constructs a new {@link DoublePropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link DoublePropertyConfig} from the contents of this builder. */
             @NonNull
             public DoublePropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new DoublePropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                return new DoublePropertyConfig(bundle);
             }
         }
     }
@@ -597,14 +579,12 @@
 
         /** Builder for {@link BooleanPropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link BooleanPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+                mPropertyName = Objects.requireNonNull(propertyName);
             }
 
             /**
@@ -616,25 +596,20 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public BooleanPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
-            /**
-             * Constructs a new {@link BooleanPropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link BooleanPropertyConfig} from the contents of this builder. */
             @NonNull
             public BooleanPropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new BooleanPropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                return new BooleanPropertyConfig(bundle);
             }
         }
     }
@@ -647,14 +622,12 @@
 
         /** Builder for {@link BytesPropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link BytesPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+                mPropertyName = Objects.requireNonNull(propertyName);
             }
 
             /**
@@ -666,25 +639,20 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public BytesPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
-            /**
-             * Constructs a new {@link BytesPropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link BytesPropertyConfig} from the contents of this builder. */
             @NonNull
             public BytesPropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new BytesPropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                return new BytesPropertyConfig(bundle);
             }
         }
     }
@@ -715,20 +683,13 @@
             return mBundle.getBoolean(INDEX_NESTED_PROPERTIES_FIELD);
         }
 
-        /**
-         * Builder for {@link DocumentPropertyConfig}.
-         *
-         * <p>The following properties must be set, or {@link DocumentPropertyConfig} construction
-         * will fail:
-         *
-         * <ul>
-         *   <li>cardinality
-         *   <li>schemaType
-         * </ul>
-         */
+        /** Builder for {@link DocumentPropertyConfig}. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyName;
+            // TODO(b/181887768): This should be final
+            private String mSchemaType;
+            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            private boolean mShouldIndexNestedProperties = false;
 
             /**
              * Creates a new {@link DocumentPropertyConfig.Builder}.
@@ -740,11 +701,8 @@
              *     Documents of different types cannot be mixed into a single property.
              */
             public Builder(@NonNull String propertyName, @NonNull String schemaType) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
-                mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, false);
-                mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
+                mPropertyName = Objects.requireNonNull(propertyName);
+                mSchemaType = Objects.requireNonNull(schemaType);
             }
 
             /**
@@ -754,10 +712,8 @@
             @Deprecated
             @UnsupportedAppUsage
             public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-                mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
-                mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
-                mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, false);
+                mPropertyName = Objects.requireNonNull(propertyName);
+                mSchemaType = null;
             }
 
             /**
@@ -768,7 +724,7 @@
             @UnsupportedAppUsage
             @NonNull
             public Builder setSchemaType(@NonNull String schemaType) {
-                mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
+                mSchemaType = Objects.requireNonNull(schemaType);
                 return this;
             }
 
@@ -781,10 +737,9 @@
             @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
             @NonNull
             public DocumentPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
                 Preconditions.checkArgumentInRange(
                         cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                mCardinality = cardinality;
                 return this;
             }
 
@@ -798,8 +753,7 @@
             @NonNull
             public DocumentPropertyConfig.Builder setShouldIndexNestedProperties(
                     boolean indexNestedProperties) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, indexNestedProperties);
+                mShouldIndexNestedProperties = indexNestedProperties;
                 return this;
             }
 
@@ -815,19 +769,18 @@
                 return setShouldIndexNestedProperties(indexNestedProperties);
             }
 
-            /**
-             * Constructs a new {@link PropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalStateException if the builder has already been used (e.g. missing
-             *     {@code dataType}).
-             */
+            /** Constructs a new {@link PropertyConfig} from the contents of this builder. */
             @NonNull
             public DocumentPropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new DocumentPropertyConfig(mBundle);
+                Bundle bundle = new Bundle();
+                bundle.putString(NAME_FIELD, mPropertyName);
+                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
+                bundle.putInt(CARDINALITY_FIELD, mCardinality);
+                bundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, mShouldIndexNestedProperties);
+                // TODO(b/181887768): Remove checkNotNull after the deprecated constructor (which
+                //  is the only way to get null here) is removed
+                bundle.putString(SCHEMA_TYPE_FIELD, Objects.requireNonNull(mSchemaType));
+                return new DocumentPropertyConfig(bundle);
             }
         }
     }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
index 39a4884..736deab 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -892,64 +892,129 @@
     @Override
     @NonNull
     public String toString() {
-        return bundleToString(mBundle).toString();
+        return formatGenericDocumentString(this, /*indentLevel=*/ 0);
     }
 
-    private static StringBuilder bundleToString(Bundle bundle) {
+    @NonNull
+    private static String formatGenericDocumentString(
+            @NonNull GenericDocument document, int indentLevel) {
         StringBuilder stringBuilder = new StringBuilder();
-        try {
-            String[] names = bundle.keySet().toArray(new String[0]);
-            // Sort names to make output deterministic. We need a custom comparator to handle
-            // nulls (arbitrarily putting them first, similar to Comparator.nullsFirst, which is
-            // only available since N).
-            Arrays.sort(
-                    names,
-                    (@Nullable String s1, @Nullable String s2) -> {
-                        if (s1 == null) {
-                            return s2 == null ? 0 : -1;
-                        } else if (s2 == null) {
-                            return 1;
-                        } else {
-                            return s1.compareTo(s2);
-                        }
-                    });
-            for (String name : names) {
-                stringBuilder.append("{ name: '").append(name).append("' value: ");
-                Object valueObject = bundle.get(name);
-                if (valueObject == null) {
-                    stringBuilder.append("<null>");
-                } else if (valueObject instanceof Bundle) {
-                    stringBuilder.append(bundleToString((Bundle) valueObject));
-                } else if (valueObject.getClass().isArray()) {
-                    stringBuilder.append("[ ");
-                    for (int i = 0; i < Array.getLength(valueObject); i++) {
-                        Object element = Array.get(valueObject, i);
-                        stringBuilder.append("'");
-                        if (element instanceof Bundle) {
-                            stringBuilder.append(bundleToString((Bundle) element));
-                        } else {
-                            stringBuilder.append(Array.get(valueObject, i));
-                        }
-                        stringBuilder.append("' ");
-                    }
-                    stringBuilder.append("]");
-                } else if (valueObject instanceof List) {
-                    @SuppressWarnings("unchecked")
-                    List<Bundle> bundles = (List<Bundle>) valueObject;
-                    for (int i = 0; i < bundles.size(); i++) {
-                        stringBuilder.append(bundleToString(bundles.get(i)));
-                    }
-                } else {
-                    stringBuilder.append(valueObject.toString());
-                }
-                stringBuilder.append(" } ");
+        stringBuilder.append(getIndent(indentLevel)).append("{\n");
+
+        String indentLevelOneString = getIndent(indentLevel + 1);
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("namespace: \"")
+                .append(document.getNamespace())
+                .append("\",\n");
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("id: \"")
+                .append(document.getId())
+                .append("\",\n");
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("score: " + document.getScore())
+                .append(",\n");
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("schemaType: \"")
+                .append(document.getSchemaType())
+                .append("\",\n");
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("creationTimestampMillis: " + document.getCreationTimestampMillis())
+                .append(",\n");
+
+        stringBuilder
+                .append(indentLevelOneString)
+                .append("timeToLiveMillis: " + document.getTtlMillis())
+                .append(",\n");
+
+        stringBuilder.append(indentLevelOneString).append("properties: {\n");
+
+        int idx = 0;
+        for (String propertyName : document.getPropertyNames()) {
+            Object property = document.getProperty(propertyName);
+            stringBuilder
+                    .append(getIndent(indentLevel + 2))
+                    .append("\"")
+                    .append(propertyName)
+                    .append("\"")
+                    .append(": ");
+            stringBuilder.append(getPropertyString(property, indentLevel + 2));
+            if (idx != document.getPropertyNames().size() - 1) {
+                stringBuilder.append(",\n");
             }
-        } catch (RuntimeException e) {
-            // Catch any exceptions here since corrupt Bundles can throw different types of
-            // exceptions (e.g. b/38445840 & b/68937025).
-            stringBuilder.append("<error>");
+            ++idx;
         }
-        return stringBuilder;
+
+        stringBuilder.append("\n");
+        stringBuilder.append(indentLevelOneString).append("}");
+
+        stringBuilder.append("\n");
+        stringBuilder.append(getIndent(indentLevel)).append("}");
+
+        return stringBuilder.toString();
+    }
+
+    /**
+     * Creates string for property.
+     *
+     * @param property property object to create string for.
+     * @param indentLevel base indent level for property.
+     */
+    @NonNull
+    private static String getPropertyString(@NonNull Object property, int indentLevel) {
+        Objects.requireNonNull(property);
+
+        StringBuilder str = new StringBuilder("[");
+
+        if (property instanceof GenericDocument[]) {
+            GenericDocument[] documentValues = (GenericDocument[]) property;
+            for (int i = 0; i < documentValues.length; ++i) {
+                str.append("\n");
+                str.append(formatGenericDocumentString(documentValues[i], indentLevel + 1));
+                if (i != documentValues.length - 1) {
+                    str.append(", ");
+                }
+                str.append("\n");
+            }
+            str.append(getIndent(indentLevel));
+        } else {
+            int propertyArrLength = Array.getLength(property);
+            for (int i = 0; i < propertyArrLength; i++) {
+                Object propertyElement = Array.get(property, i);
+                if (propertyElement instanceof String) {
+                    str.append("\"").append(propertyElement).append("\"");
+                } else if (propertyElement instanceof byte[]) {
+                    str.append(Arrays.toString((byte[]) propertyElement));
+                } else {
+                    str.append(propertyElement);
+                }
+                if (i != propertyArrLength - 1) {
+                    str.append(", ");
+                }
+            }
+        }
+
+        str.append("]");
+        return str.toString();
+    }
+
+    /** Creates string for given indent level. */
+    @NonNull
+    private static String getIndent(int indentLevel) {
+        StringBuilder indentedString = new StringBuilder();
+        for (int i = 0; i < indentLevel; ++i) {
+            indentedString.append("  ");
+        }
+        return indentedString.toString();
     }
 
     /**
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
index 58fd8be..e324b9f 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
@@ -20,8 +20,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -102,15 +100,11 @@
         return mTypePropertyPathsMap;
     }
 
-    /**
-     * Builder for {@link GetByDocumentIdRequest} objects.
-     *
-     * <p>Once {@link #build} is called, the instance can no longer be used.
-     */
+    /** Builder for {@link GetByDocumentIdRequest} objects. */
     public static final class Builder {
         private final String mNamespace;
-        private final Set<String> mIds = new ArraySet<>();
-        private final Map<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
+        private ArraySet<String> mIds = new ArraySet<>();
+        private ArrayMap<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
         private boolean mBuilt = false;
 
         /** Creates a {@link GetByDocumentIdRequest.Builder} instance. */
@@ -118,26 +112,19 @@
             mNamespace = Objects.requireNonNull(namespace);
         }
 
-        /**
-         * Adds one or more document IDs to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds one or more document IDs to the request. */
         @NonNull
         public Builder addIds(@NonNull String... ids) {
             Objects.requireNonNull(ids);
+            resetIfBuilt();
             return addIds(Arrays.asList(ids));
         }
 
-        /**
-         * Adds a collection of IDs to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds a collection of IDs to the request. */
         @NonNull
         public Builder addIds(@NonNull Collection<String> ids) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(ids);
+            resetIfBuilt();
             mIds.addAll(ids);
             return this;
         }
@@ -156,15 +143,14 @@
          * apply to all results, excepting any types that have their own, specific property paths
          * set.
          *
-         * @throws IllegalStateException if the builder has already been used.
          * @see SearchSpec.Builder#addProjection
          */
         @NonNull
         public Builder addProjection(
                 @NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(schemaType);
             Objects.requireNonNull(propertyPaths);
+            resetIfBuilt();
             List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
             for (String propertyPath : propertyPaths) {
                 Objects.requireNonNull(propertyPath);
@@ -174,16 +160,23 @@
             return this;
         }
 
-        /**
-         * Builds a new {@link GetByDocumentIdRequest}.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Builds a new {@link GetByDocumentIdRequest}. */
         @NonNull
         public GetByDocumentIdRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             mBuilt = true;
-            return new GetByDocumentIdRequest(mNamespace, mIds, mProjectionTypePropertyPaths);
+            return new GetByDocumentIdRequest(
+                    mNamespace, new ArraySet<>(mIds), new ArrayMap<>(mProjectionTypePropertyPaths));
+        }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mIds = new ArraySet<>(mIds);
+                // No need to clone each propertyPathsList inside mProjectionTypePropertyPaths since
+                // the builder only replaces it, never adds to it. So even if the builder is used
+                // again, the previous one will remain with the object.
+                mProjectionTypePropertyPaths = new ArrayMap<>(mProjectionTypePropertyPaths);
+                mBuilt = false;
+            }
         }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
index 6f8cbe8..8816c78 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
@@ -21,8 +21,6 @@
 import android.os.Bundle;
 import android.util.ArraySet;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.ArrayList;
 import java.util.Objects;
 import java.util.Set;
@@ -76,8 +74,8 @@
     /** Builder for {@link GetSchemaResponse} objects. */
     public static final class Builder {
         private int mVersion = 0;
+        private ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
         private boolean mBuilt = false;
-        private final ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
 
         /**
          * Sets the database overall schema version.
@@ -86,6 +84,7 @@
          */
         @NonNull
         public Builder setVersion(@IntRange(from = 0) int version) {
+            resetIfBuilt();
             mVersion = version;
             return this;
         }
@@ -93,6 +92,8 @@
         /** Adds one {@link AppSearchSchema} to the schema list. */
         @NonNull
         public Builder addSchema(@NonNull AppSearchSchema schema) {
+            Objects.requireNonNull(schema);
+            resetIfBuilt();
             mSchemaBundles.add(schema.getBundle());
             return this;
         }
@@ -100,12 +101,18 @@
         /** Builds a {@link GetSchemaResponse} object. */
         @NonNull
         public GetSchemaResponse build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Bundle bundle = new Bundle();
             bundle.putInt(VERSION_FIELD, mVersion);
             bundle.putParcelableArrayList(SCHEMAS_FIELD, mSchemaBundles);
             mBuilt = true;
             return new GetSchemaResponse(bundle);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mSchemaBundles = new ArrayList<>(mSchemaBundles);
+                mBuilt = false;
+            }
+        }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
index b49e0e8..3424128 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
@@ -19,8 +19,6 @@
 
 import android.annotation.NonNull;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -46,50 +44,41 @@
         return Collections.unmodifiableList(mDocuments);
     }
 
-    /**
-     * Builder for {@link PutDocumentsRequest} objects.
-     *
-     * <p>Once {@link #build} is called, the instance can no longer be used.
-     */
+    /** Builder for {@link PutDocumentsRequest} objects. */
     public static final class Builder {
-        private final List<GenericDocument> mDocuments = new ArrayList<>();
+        private ArrayList<GenericDocument> mDocuments = new ArrayList<>();
         private boolean mBuilt = false;
 
-        /**
-         * Adds one or more {@link GenericDocument} objects to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds one or more {@link GenericDocument} objects to the request. */
         @NonNull
         public Builder addGenericDocuments(@NonNull GenericDocument... documents) {
             Objects.requireNonNull(documents);
+            resetIfBuilt();
             return addGenericDocuments(Arrays.asList(documents));
         }
 
-        /**
-         * Adds a collection of {@link GenericDocument} objects to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds a collection of {@link GenericDocument} objects to the request. */
         @NonNull
         public Builder addGenericDocuments(
                 @NonNull Collection<? extends GenericDocument> documents) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(documents);
+            resetIfBuilt();
             mDocuments.addAll(documents);
             return this;
         }
 
-        /**
-         * Creates a new {@link PutDocumentsRequest} object.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Creates a new {@link PutDocumentsRequest} object. */
         @NonNull
         public PutDocumentsRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             mBuilt = true;
             return new PutDocumentsRequest(mDocuments);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mDocuments = new ArrayList<>(mDocuments);
+                mBuilt = false;
+            }
+        }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
index 1afbe27..b86fd27 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.util.ArraySet;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -54,14 +52,10 @@
         return Collections.unmodifiableSet(mIds);
     }
 
-    /**
-     * Builder for {@link RemoveByDocumentIdRequest} objects.
-     *
-     * <p>Once {@link #build} is called, the instance can no longer be used.
-     */
+    /** Builder for {@link RemoveByDocumentIdRequest} objects. */
     public static final class Builder {
         private final String mNamespace;
-        private final Set<String> mIds = new ArraySet<>();
+        private ArraySet<String> mIds = new ArraySet<>();
         private boolean mBuilt = false;
 
         /** Creates a {@link RemoveByDocumentIdRequest.Builder} instance. */
@@ -69,40 +63,35 @@
             mNamespace = Objects.requireNonNull(namespace);
         }
 
-        /**
-         * Adds one or more document IDs to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds one or more document IDs to the request. */
         @NonNull
         public Builder addIds(@NonNull String... ids) {
             Objects.requireNonNull(ids);
+            resetIfBuilt();
             return addIds(Arrays.asList(ids));
         }
 
-        /**
-         * Adds a collection of IDs to the request.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Adds a collection of IDs to the request. */
         @NonNull
         public Builder addIds(@NonNull Collection<String> ids) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(ids);
+            resetIfBuilt();
             mIds.addAll(ids);
             return this;
         }
 
-        /**
-         * Builds a new {@link RemoveByDocumentIdRequest}.
-         *
-         * @throws IllegalStateException if the builder has already been used.
-         */
+        /** Builds a new {@link RemoveByDocumentIdRequest}. */
         @NonNull
         public RemoveByDocumentIdRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             mBuilt = true;
             return new RemoveByDocumentIdRequest(mNamespace, mIds);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mIds = new ArraySet<>(mIds);
+                mBuilt = false;
+            }
+        }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
index 3947ba7..b6575c2 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
@@ -19,8 +19,6 @@
 import android.annotation.CurrentTimeMillisLong;
 import android.annotation.NonNull;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Objects;
 
 /**
@@ -94,7 +92,6 @@
         private final String mNamespace;
         private final String mDocumentId;
         private Long mUsageTimestampMillis;
-        private boolean mBuilt = false;
 
         /** Creates a {@link ReportSystemUsageRequest.Builder} instance. */
         public Builder(
@@ -116,29 +113,20 @@
          *
          * <p>If unset, this defaults to the current timestamp at the time that the {@link
          * ReportSystemUsageRequest} is constructed.
-         *
-         * @throws IllegalStateException if the builder has already been used
          */
         @NonNull
         public ReportSystemUsageRequest.Builder setUsageTimestampMillis(
                 @CurrentTimeMillisLong long usageTimestampMillis) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             mUsageTimestampMillis = usageTimestampMillis;
             return this;
         }
 
-        /**
-         * Builds a new {@link ReportSystemUsageRequest}.
-         *
-         * @throws IllegalStateException if the builder has already been used
-         */
+        /** Builds a new {@link ReportSystemUsageRequest}. */
         @NonNull
         public ReportSystemUsageRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             if (mUsageTimestampMillis == null) {
                 mUsageTimestampMillis = System.currentTimeMillis();
             }
-            mBuilt = true;
             return new ReportSystemUsageRequest(
                     mPackageName, mDatabase, mNamespace, mDocumentId, mUsageTimestampMillis);
         }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
index 5cb59b3..59fa6e0 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
@@ -20,8 +20,6 @@
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Objects;
 
 /**
@@ -72,7 +70,6 @@
         // TODO(b/181887768): Make this final
         private String mDocumentId;
         private Long mUsageTimestampMillis;
-        private boolean mBuilt = false;
 
         /** Creates a {@link ReportUsageRequest.Builder} instance. */
         public Builder(@NonNull String namespace, @NonNull String documentId) {
@@ -122,29 +119,20 @@
          *
          * <p>If unset, this defaults to the current timestamp at the time that the {@link
          * ReportUsageRequest} is constructed.
-         *
-         * @throws IllegalStateException if the builder has already been used
          */
         @NonNull
         public ReportUsageRequest.Builder setUsageTimestampMillis(
                 @CurrentTimeMillisLong long usageTimestampMillis) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             mUsageTimestampMillis = usageTimestampMillis;
             return this;
         }
 
-        /**
-         * Builds a new {@link ReportUsageRequest}.
-         *
-         * @throws IllegalStateException if the builder has already been used
-         */
+        /** Builds a new {@link ReportUsageRequest}. */
         @NonNull
         public ReportUsageRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             if (mUsageTimestampMillis == null) {
                 mUsageTimestampMillis = System.currentTimeMillis();
             }
-            mBuilt = true;
             return new ReportUsageRequest(mNamespace, mDocumentId, mUsageTimestampMillis);
         }
     }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
index 9a1796c..0d186f2 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
@@ -164,10 +164,12 @@
 
     /** Builder for {@link SearchResult} objects. */
     public static final class Builder {
-        private final Bundle mBundle = new Bundle();
-        private final ArrayList<Bundle> mMatchInfos = new ArrayList<>();
-
-        private boolean mBuilt;
+        private final String mPackageName;
+        private final String mDatabaseName;
+        private ArrayList<Bundle> mMatchInfoBundles = new ArrayList<>();
+        private GenericDocument mGenericDocument;
+        private double mRankingSignal;
+        private boolean mBuilt = false;
 
         /**
          * Constructs a new builder for {@link SearchResult} objects.
@@ -176,19 +178,16 @@
          * @param databaseName the database name the matched document belongs to.
          */
         public Builder(@NonNull String packageName, @NonNull String databaseName) {
-            mBundle.putString(PACKAGE_NAME_FIELD, Objects.requireNonNull(packageName));
-            mBundle.putString(DATABASE_NAME_FIELD, Objects.requireNonNull(databaseName));
+            mPackageName = Objects.requireNonNull(packageName);
+            mDatabaseName = Objects.requireNonNull(databaseName);
         }
 
-        /**
-         * Sets the document which matched.
-         *
-         * @throws IllegalStateException if the builder has already been used
-         */
+        /** Sets the document which matched. */
         @NonNull
         public Builder setGenericDocument(@NonNull GenericDocument document) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putBundle(DOCUMENT_FIELD, document.getBundle());
+            Objects.requireNonNull(document);
+            resetIfBuilt();
+            mGenericDocument = document;
             return this;
         }
 
@@ -202,34 +201,41 @@
         /** Adds another match to this SearchResult. */
         @NonNull
         public Builder addMatchInfo(@NonNull MatchInfo matchInfo) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkState(
                     matchInfo.mDocument == null,
                     "This MatchInfo is already associated with a SearchResult and can't be "
                             + "reassigned");
-            mMatchInfos.add(matchInfo.mBundle);
+            resetIfBuilt();
+            mMatchInfoBundles.add(matchInfo.mBundle);
             return this;
         }
 
         /** Sets the ranking signal of the matched document in this SearchResult. */
         @NonNull
         public Builder setRankingSignal(double rankingSignal) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putDouble(RANKING_SIGNAL_FIELD, rankingSignal);
+            resetIfBuilt();
+            mRankingSignal = rankingSignal;
             return this;
         }
 
-        /**
-         * Constructs a new {@link SearchResult}.
-         *
-         * @throws IllegalStateException if the builder has already been used
-         */
+        /** Constructs a new {@link SearchResult}. */
         @NonNull
         public SearchResult build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putParcelableArrayList(MATCH_INFOS_FIELD, mMatchInfos);
+            Bundle bundle = new Bundle();
+            bundle.putString(PACKAGE_NAME_FIELD, mPackageName);
+            bundle.putString(DATABASE_NAME_FIELD, mDatabaseName);
+            bundle.putBundle(DOCUMENT_FIELD, mGenericDocument.getBundle());
+            bundle.putDouble(RANKING_SIGNAL_FIELD, mRankingSignal);
+            bundle.putParcelableArrayList(MATCH_INFOS_FIELD, mMatchInfoBundles);
             mBuilt = true;
-            return new SearchResult(mBundle);
+            return new SearchResult(bundle);
+        }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mMatchInfoBundles = new ArrayList<>(mMatchInfoBundles);
+                mBuilt = false;
+            }
         }
     }
 
@@ -441,8 +447,9 @@
 
         /** Builder for {@link MatchInfo} objects. */
         public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
+            private final String mPropertyPath;
+            private MatchRange mExactMatchRange = new MatchRange(0, 0);
+            private MatchRange mSnippetRange = new MatchRange(0, 0);
 
             /**
              * Creates a new {@link MatchInfo.Builder} reporting a match with the given property
@@ -458,49 +465,33 @@
              *                     which property in the document these snippets correspond to.
              */
             public Builder(@NonNull String propertyPath) {
-                mBundle.putString(
-                        SearchResult.MatchInfo.PROPERTY_PATH_FIELD,
-                        Objects.requireNonNull(propertyPath));
+                mPropertyPath = Objects.requireNonNull(propertyPath);
             }
 
-            /**
-             * Sets the exact {@link MatchRange} corresponding to the given entry.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Sets the exact {@link MatchRange} corresponding to the given entry. */
             @NonNull
             public Builder setExactMatchRange(@NonNull MatchRange matchRange) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Objects.requireNonNull(matchRange);
-                mBundle.putInt(MatchInfo.EXACT_MATCH_RANGE_LOWER_FIELD, matchRange.getStart());
-                mBundle.putInt(MatchInfo.EXACT_MATCH_RANGE_UPPER_FIELD, matchRange.getEnd());
+                mExactMatchRange = Objects.requireNonNull(matchRange);
                 return this;
             }
 
-            /**
-             * Sets the snippet {@link MatchRange} corresponding to the given entry.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Sets the snippet {@link MatchRange} corresponding to the given entry. */
             @NonNull
             public Builder setSnippetRange(@NonNull MatchRange matchRange) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Objects.requireNonNull(matchRange);
-                mBundle.putInt(MatchInfo.SNIPPET_RANGE_LOWER_FIELD, matchRange.getStart());
-                mBundle.putInt(MatchInfo.SNIPPET_RANGE_UPPER_FIELD, matchRange.getEnd());
+                mSnippetRange = Objects.requireNonNull(matchRange);
                 return this;
             }
 
-            /**
-             * Constructs a new {@link MatchInfo}.
-             *
-             * @throws IllegalStateException if the builder has already been used
-             */
+            /** Constructs a new {@link MatchInfo}. */
             @NonNull
             public MatchInfo build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new MatchInfo(mBundle, /*document=*/ null);
+                Bundle bundle = new Bundle();
+                bundle.putString(SearchResult.MatchInfo.PROPERTY_PATH_FIELD, mPropertyPath);
+                bundle.putInt(MatchInfo.EXACT_MATCH_RANGE_LOWER_FIELD, mExactMatchRange.getStart());
+                bundle.putInt(MatchInfo.EXACT_MATCH_RANGE_UPPER_FIELD, mExactMatchRange.getEnd());
+                bundle.putInt(MatchInfo.SNIPPET_RANGE_LOWER_FIELD, mSnippetRange.getStart());
+                bundle.putInt(MatchInfo.SNIPPET_RANGE_UPPER_FIELD, mSnippetRange.getEnd());
+                return new MatchInfo(bundle, /*document=*/ null);
             }
         }
     }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
index 1c57c75..5abd4f6 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
@@ -20,6 +20,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
+import android.app.appsearch.util.BundleUtil;
 import android.os.Bundle;
 import android.util.ArrayMap;
 
@@ -310,22 +311,22 @@
 
     /** Builder for {@link SearchSpec objects}. */
     public static final class Builder {
+        private ArrayList<String> mSchemas = new ArrayList<>();
+        private ArrayList<String> mNamespaces = new ArrayList<>();
+        private ArrayList<String> mPackageNames = new ArrayList<>();
+        private Bundle mProjectionTypePropertyMasks = new Bundle();
 
-        private final Bundle mBundle;
-        private final ArrayList<String> mSchemas = new ArrayList<>();
-        private final ArrayList<String> mNamespaces = new ArrayList<>();
-        private final ArrayList<String> mPackageNames = new ArrayList<>();
-        private final Bundle mProjectionTypePropertyMasks = new Bundle();
+        private int mResultCountPerPage = DEFAULT_NUM_PER_PAGE;
+        private @TermMatch int mTermMatchType = TERM_MATCH_PREFIX;
+        private int mSnippetCount = 0;
+        private int mSnippetCountPerProperty = MAX_SNIPPET_PER_PROPERTY_COUNT;
+        private int mMaxSnippetSize = 0;
+        private @RankingStrategy int mRankingStrategy = RANKING_STRATEGY_NONE;
+        private @Order int mOrder = ORDER_DESCENDING;
+        private @GroupingType int mGroupingTypeFlags = 0;
+        private int mGroupingLimit = 0;
         private boolean mBuilt = false;
 
-        /** Creates a new {@link SearchSpec.Builder}. */
-        public Builder() {
-            mBundle = new Bundle();
-            mBundle.putInt(NUM_PER_PAGE_FIELD, DEFAULT_NUM_PER_PAGE);
-            mBundle.putInt(TERM_MATCH_TYPE_FIELD, TERM_MATCH_PREFIX);
-            mBundle.putInt(SNIPPET_COUNT_PER_PROPERTY_FIELD, MAX_SNIPPET_PER_PROPERTY_COUNT);
-        }
-
         /**
          * Indicates how the query terms should match {@code TermMatchCode} in the index.
          *
@@ -333,11 +334,11 @@
          * SearchSpec#TERM_MATCH_PREFIX}.
          */
         @NonNull
-        public Builder setTermMatch(@TermMatch int termMatchTypeCode) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+        public Builder setTermMatch(@TermMatch int termMatchType) {
             Preconditions.checkArgumentInRange(
-                    termMatchTypeCode, TERM_MATCH_EXACT_ONLY, TERM_MATCH_PREFIX, "Term match type");
-            mBundle.putInt(TERM_MATCH_TYPE_FIELD, termMatchTypeCode);
+                    termMatchType, TERM_MATCH_EXACT_ONLY, TERM_MATCH_PREFIX, "Term match type");
+            resetIfBuilt();
+            mTermMatchType = termMatchType;
             return this;
         }
 
@@ -350,7 +351,7 @@
         @NonNull
         public Builder addFilterSchemas(@NonNull String... schemas) {
             Objects.requireNonNull(schemas);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             return addFilterSchemas(Arrays.asList(schemas));
         }
 
@@ -363,7 +364,7 @@
         @NonNull
         public Builder addFilterSchemas(@NonNull Collection<String> schemas) {
             Objects.requireNonNull(schemas);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             mSchemas.addAll(schemas);
             return this;
         }
@@ -377,7 +378,7 @@
         @NonNull
         public Builder addFilterNamespaces(@NonNull String... namespaces) {
             Objects.requireNonNull(namespaces);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             return addFilterNamespaces(Arrays.asList(namespaces));
         }
 
@@ -390,7 +391,7 @@
         @NonNull
         public Builder addFilterNamespaces(@NonNull Collection<String> namespaces) {
             Objects.requireNonNull(namespaces);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             mNamespaces.addAll(namespaces);
             return this;
         }
@@ -406,7 +407,7 @@
         @NonNull
         public Builder addFilterPackageNames(@NonNull String... packageNames) {
             Objects.requireNonNull(packageNames);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             return addFilterPackageNames(Arrays.asList(packageNames));
         }
 
@@ -421,7 +422,7 @@
         @NonNull
         public Builder addFilterPackageNames(@NonNull Collection<String> packageNames) {
             Objects.requireNonNull(packageNames);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
             mPackageNames.addAll(packageNames);
             return this;
         }
@@ -433,23 +434,24 @@
          */
         @NonNull
         public SearchSpec.Builder setResultCountPerPage(
-                @IntRange(from = 0, to = MAX_NUM_PER_PAGE) int numPerPage) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkArgumentInRange(numPerPage, 0, MAX_NUM_PER_PAGE, "NumPerPage");
-            mBundle.putInt(NUM_PER_PAGE_FIELD, numPerPage);
+                @IntRange(from = 0, to = MAX_NUM_PER_PAGE) int resultCountPerPage) {
+            Preconditions.checkArgumentInRange(
+                    resultCountPerPage, 0, MAX_NUM_PER_PAGE, "resultCountPerPage");
+            resetIfBuilt();
+            mResultCountPerPage = resultCountPerPage;
             return this;
         }
 
         /** Sets ranking strategy for AppSearch results. */
         @NonNull
         public Builder setRankingStrategy(@RankingStrategy int rankingStrategy) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(
                     rankingStrategy,
                     RANKING_STRATEGY_NONE,
                     RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP,
                     "Result ranking strategy");
-            mBundle.putInt(RANKING_STRATEGY_FIELD, rankingStrategy);
+            resetIfBuilt();
+            mRankingStrategy = rankingStrategy;
             return this;
         }
 
@@ -461,10 +463,10 @@
          */
         @NonNull
         public Builder setOrder(@Order int order) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(
                     order, ORDER_DESCENDING, ORDER_ASCENDING, "Result ranking order");
-            mBundle.putInt(ORDER_FIELD, order);
+            resetIfBuilt();
+            mOrder = order;
             return this;
         }
 
@@ -481,9 +483,9 @@
         @NonNull
         public SearchSpec.Builder setSnippetCount(
                 @IntRange(from = 0, to = MAX_SNIPPET_COUNT) int snippetCount) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(snippetCount, 0, MAX_SNIPPET_COUNT, "snippetCount");
-            mBundle.putInt(SNIPPET_COUNT_FIELD, snippetCount);
+            resetIfBuilt();
+            mSnippetCount = snippetCount;
             return this;
         }
 
@@ -502,13 +504,13 @@
         public SearchSpec.Builder setSnippetCountPerProperty(
                 @IntRange(from = 0, to = MAX_SNIPPET_PER_PROPERTY_COUNT)
                         int snippetCountPerProperty) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(
                     snippetCountPerProperty,
                     0,
                     MAX_SNIPPET_PER_PROPERTY_COUNT,
                     "snippetCountPerProperty");
-            mBundle.putInt(SNIPPET_COUNT_PER_PROPERTY_FIELD, snippetCountPerProperty);
+            resetIfBuilt();
+            mSnippetCountPerProperty = snippetCountPerProperty;
             return this;
         }
 
@@ -527,10 +529,10 @@
         @NonNull
         public SearchSpec.Builder setMaxSnippetSize(
                 @IntRange(from = 0, to = MAX_SNIPPET_SIZE_LIMIT) int maxSnippetSize) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(
                     maxSnippetSize, 0, MAX_SNIPPET_SIZE_LIMIT, "maxSnippetSize");
-            mBundle.putInt(MAX_SNIPPET_FIELD, maxSnippetSize);
+            resetIfBuilt();
+            mMaxSnippetSize = maxSnippetSize;
             return this;
         }
 
@@ -599,9 +601,9 @@
         @NonNull
         public SearchSpec.Builder addProjection(
                 @NonNull String schema, @NonNull Collection<String> propertyPaths) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(schema);
             Objects.requireNonNull(propertyPaths);
+            resetIfBuilt();
             ArrayList<String> propertyPathsArrayList = new ArrayList<>(propertyPaths.size());
             for (String propertyPath : propertyPaths) {
                 Objects.requireNonNull(propertyPath);
@@ -634,25 +636,41 @@
         public Builder setResultGrouping(@GroupingType int groupingTypeFlags, int limit) {
             Preconditions.checkState(
                     groupingTypeFlags != 0, "Result grouping type cannot be zero.");
-            mBundle.putInt(RESULT_GROUPING_TYPE_FLAGS, groupingTypeFlags);
-            mBundle.putInt(RESULT_GROUPING_LIMIT, limit);
+            resetIfBuilt();
+            mGroupingTypeFlags = groupingTypeFlags;
+            mGroupingLimit = limit;
             return this;
         }
 
-        /**
-         * Constructs a new {@link SearchSpec} from the contents of this builder.
-         *
-         * <p>After calling this method, the builder must no longer be used.
-         */
+        /** Constructs a new {@link SearchSpec} from the contents of this builder. */
         @NonNull
         public SearchSpec build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
-            mBundle.putStringArrayList(SCHEMA_FIELD, mSchemas);
-            mBundle.putStringArrayList(PACKAGE_NAME_FIELD, mPackageNames);
-            mBundle.putBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD, mProjectionTypePropertyMasks);
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(SCHEMA_FIELD, mSchemas);
+            bundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
+            bundle.putStringArrayList(PACKAGE_NAME_FIELD, mPackageNames);
+            bundle.putBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD, mProjectionTypePropertyMasks);
+            bundle.putInt(NUM_PER_PAGE_FIELD, mResultCountPerPage);
+            bundle.putInt(TERM_MATCH_TYPE_FIELD, mTermMatchType);
+            bundle.putInt(SNIPPET_COUNT_FIELD, mSnippetCount);
+            bundle.putInt(SNIPPET_COUNT_PER_PROPERTY_FIELD, mSnippetCountPerProperty);
+            bundle.putInt(MAX_SNIPPET_FIELD, mMaxSnippetSize);
+            bundle.putInt(RANKING_STRATEGY_FIELD, mRankingStrategy);
+            bundle.putInt(ORDER_FIELD, mOrder);
+            bundle.putInt(RESULT_GROUPING_TYPE_FLAGS, mGroupingTypeFlags);
+            bundle.putInt(RESULT_GROUPING_LIMIT, mGroupingLimit);
             mBuilt = true;
-            return new SearchSpec(mBundle);
+            return new SearchSpec(bundle);
+        }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mSchemas = new ArrayList<>(mSchemas);
+                mNamespaces = new ArrayList<>(mNamespaces);
+                mPackageNames = new ArrayList<>(mPackageNames);
+                mProjectionTypePropertyMasks = BundleUtil.deepCopy(mProjectionTypePropertyMasks);
+                mBuilt = false;
+            }
         }
     }
 }
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 275b2c3..96002c5 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -167,17 +167,13 @@
         return mVersion;
     }
 
-    /**
-     * Builder for {@link SetSchemaRequest} objects.
-     *
-     * <p>Once {@link #build} is called, the instance can no longer be used.
-     */
+    /** Builder for {@link SetSchemaRequest} objects. */
     public static final class Builder {
-        private final Set<AppSearchSchema> mSchemas = new ArraySet<>();
-        private final Set<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
-        private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
+        private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>();
+        private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
+        private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
                 new ArrayMap<>();
-        private final Map<String, Migrator> mMigrators = new ArrayMap<>();
+        private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
         private boolean mForceOverride = false;
         private int mVersion = 1;
         private boolean mBuilt = false;
@@ -188,12 +184,11 @@
          * <p>An {@link AppSearchSchema} object represents one type of structured data.
          *
          * <p>Any documents of these types will be displayed on system UI surfaces by default.
-         *
-         * @throws IllegalStateException if the builder has already been used.
          */
         @NonNull
         public Builder addSchemas(@NonNull AppSearchSchema... schemas) {
             Objects.requireNonNull(schemas);
+            resetIfBuilt();
             return addSchemas(Arrays.asList(schemas));
         }
 
@@ -201,13 +196,11 @@
          * Adds a collection of {@link AppSearchSchema} objects to the schema.
          *
          * <p>An {@link AppSearchSchema} object represents one type of structured data.
-         *
-         * @throws IllegalStateException if the builder has already been used.
          */
         @NonNull
         public Builder addSchemas(@NonNull Collection<AppSearchSchema> schemas) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Objects.requireNonNull(schemas);
+            resetIfBuilt();
             mSchemas.addAll(schemas);
             return this;
         }
@@ -225,7 +218,6 @@
          * @param schemaType The name of an {@link AppSearchSchema} within the same {@link
          *     SetSchemaRequest}, which will be configured.
          * @param displayed Whether documents of this type will be displayed on system UI surfaces.
-         * @throws IllegalStateException if the builder has already been used.
          */
         // Merged list available from getSchemasNotDisplayedBySystem
         @SuppressLint("MissingGetterMatchingBuilder")
@@ -233,8 +225,7 @@
         public Builder setSchemaTypeDisplayedBySystem(
                 @NonNull String schemaType, boolean displayed) {
             Objects.requireNonNull(schemaType);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-
+            resetIfBuilt();
             if (displayed) {
                 mSchemasNotDisplayedBySystem.remove(schemaType);
             } else {
@@ -262,7 +253,6 @@
          * @param schemaType The schema type to set visibility on.
          * @param visible Whether the {@code schemaType} will be visible or not.
          * @param packageIdentifier Represents the package that will be granted visibility.
-         * @throws IllegalStateException if the builder has already been used.
          */
         // Merged list available from getSchemasVisibleToPackages
         @SuppressLint("MissingGetterMatchingBuilder")
@@ -273,7 +263,7 @@
                 @NonNull PackageIdentifier packageIdentifier) {
             Objects.requireNonNull(schemaType);
             Objects.requireNonNull(packageIdentifier);
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            resetIfBuilt();
 
             Set<PackageIdentifier> packageIdentifiers = mSchemasVisibleToPackages.get(schemaType);
             if (visible) {
@@ -324,6 +314,7 @@
         public Builder setMigrator(@NonNull String schemaType, @NonNull Migrator migrator) {
             Objects.requireNonNull(schemaType);
             Objects.requireNonNull(migrator);
+            resetIfBuilt();
             mMigrators.put(schemaType, migrator);
             return this;
         }
@@ -352,6 +343,7 @@
         @NonNull
         public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
             Objects.requireNonNull(migrators);
+            resetIfBuilt();
             mMigrators.putAll(migrators);
             return this;
         }
@@ -369,6 +361,7 @@
          */
         @NonNull
         public Builder setForceOverride(boolean forceOverride) {
+            resetIfBuilt();
             mForceOverride = forceOverride;
             return this;
         }
@@ -391,8 +384,7 @@
          * @param version A positive integer representing the version of the entire set of schemas
          *     represents the version of the whole schema in the {@link AppSearchSession} database,
          *     default version is 1.
-         * @throws IllegalStateException if the version is negative or the builder has already been
-         *     used.
+         * @throws IllegalArgumentException if the version is negative.
          * @see AppSearchSession#setSchema
          * @see Migrator
          * @see SetSchemaRequest.Builder#setMigrator
@@ -400,6 +392,7 @@
         @NonNull
         public Builder setVersion(@IntRange(from = 1) int version) {
             Preconditions.checkArgument(version >= 1, "Version must be a positive number.");
+            resetIfBuilt();
             mVersion = version;
             return this;
         }
@@ -409,12 +402,9 @@
          *
          * @throws IllegalArgumentException if schema types were referenced, but the corresponding
          *     {@link AppSearchSchema} type was never added.
-         * @throws IllegalStateException if the builder has already been used.
          */
         @NonNull
         public SetSchemaRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-
             // Verify that any schema types with display or visibility settings refer to a real
             // schema.
             // Create a copy because we're going to remove from the set for verification purposes.
@@ -440,5 +430,22 @@
                     mForceOverride,
                     mVersion);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                ArrayMap<String, Set<PackageIdentifier>> schemasVisibleToPackages =
+                        new ArrayMap<>(mSchemasVisibleToPackages.size());
+                for (Map.Entry<String, Set<PackageIdentifier>> entry :
+                        mSchemasVisibleToPackages.entrySet()) {
+                    schemasVisibleToPackages.put(entry.getKey(), new ArraySet<>(entry.getValue()));
+                }
+                mSchemasVisibleToPackages = schemasVisibleToPackages;
+
+                mSchemas = new ArraySet<>(mSchemas);
+                mSchemasNotDisplayedBySystem = new ArraySet<>(mSchemasNotDisplayedBySystem);
+                mMigrators = new ArrayMap<>(mMigrators);
+                mBuilt = false;
+            }
+        }
     }
 }
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
index 7ad5fe8..2c75b71 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
@@ -179,81 +179,88 @@
 
     /** Builder for {@link SetSchemaResponse} objects. */
     public static final class Builder {
-        private final ArrayList<MigrationFailure> mMigrationFailures = new ArrayList<>();
-        private final ArrayList<String> mDeletedTypes = new ArrayList<>();
-        private final ArrayList<String> mMigratedTypes = new ArrayList<>();
-        private final ArrayList<String> mIncompatibleTypes = new ArrayList<>();
+        private List<MigrationFailure> mMigrationFailures = new ArrayList<>();
+        private ArrayList<String> mDeletedTypes = new ArrayList<>();
+        private ArrayList<String> mMigratedTypes = new ArrayList<>();
+        private ArrayList<String> mIncompatibleTypes = new ArrayList<>();
         private boolean mBuilt = false;
 
         /** Adds {@link MigrationFailure}s to the list of migration failures. */
         @NonNull
         public Builder addMigrationFailures(
                 @NonNull Collection<MigrationFailure> migrationFailures) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mMigrationFailures.addAll(Objects.requireNonNull(migrationFailures));
+            Objects.requireNonNull(migrationFailures);
+            resetIfBuilt();
+            mMigrationFailures.addAll(migrationFailures);
             return this;
         }
 
         /** Adds a {@link MigrationFailure} to the list of migration failures. */
         @NonNull
         public Builder addMigrationFailure(@NonNull MigrationFailure migrationFailure) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mMigrationFailures.add(Objects.requireNonNull(migrationFailure));
+            Objects.requireNonNull(migrationFailure);
+            resetIfBuilt();
+            mMigrationFailures.add(migrationFailure);
             return this;
         }
 
         /** Adds deletedTypes to the list of deleted schema types. */
         @NonNull
         public Builder addDeletedTypes(@NonNull Collection<String> deletedTypes) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mDeletedTypes.addAll(Objects.requireNonNull(deletedTypes));
+            Objects.requireNonNull(deletedTypes);
+            resetIfBuilt();
+            mDeletedTypes.addAll(deletedTypes);
             return this;
         }
 
         /** Adds one deletedType to the list of deleted schema types. */
         @NonNull
         public Builder addDeletedType(@NonNull String deletedType) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mDeletedTypes.add(Objects.requireNonNull(deletedType));
+            Objects.requireNonNull(deletedType);
+            resetIfBuilt();
+            mDeletedTypes.add(deletedType);
             return this;
         }
 
         /** Adds incompatibleTypes to the list of incompatible schema types. */
         @NonNull
         public Builder addIncompatibleTypes(@NonNull Collection<String> incompatibleTypes) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mIncompatibleTypes.addAll(Objects.requireNonNull(incompatibleTypes));
+            Objects.requireNonNull(incompatibleTypes);
+            resetIfBuilt();
+            mIncompatibleTypes.addAll(incompatibleTypes);
             return this;
         }
 
         /** Adds one incompatibleType to the list of incompatible schema types. */
         @NonNull
         public Builder addIncompatibleType(@NonNull String incompatibleType) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mIncompatibleTypes.add(Objects.requireNonNull(incompatibleType));
+            Objects.requireNonNull(incompatibleType);
+            resetIfBuilt();
+            mIncompatibleTypes.add(incompatibleType);
             return this;
         }
 
         /** Adds migratedTypes to the list of migrated schema types. */
         @NonNull
         public Builder addMigratedTypes(@NonNull Collection<String> migratedTypes) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mMigratedTypes.addAll(Objects.requireNonNull(migratedTypes));
+            Objects.requireNonNull(migratedTypes);
+            resetIfBuilt();
+            mMigratedTypes.addAll(migratedTypes);
             return this;
         }
 
         /** Adds one migratedType to the list of migrated schema types. */
         @NonNull
         public Builder addMigratedType(@NonNull String migratedType) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mMigratedTypes.add(Objects.requireNonNull(migratedType));
+            Objects.requireNonNull(migratedType);
+            resetIfBuilt();
+            mMigratedTypes.add(migratedType);
             return this;
         }
 
         /** Builds a {@link SetSchemaResponse} object. */
         @NonNull
         public SetSchemaResponse build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
             Bundle bundle = new Bundle();
             bundle.putStringArrayList(INCOMPATIBLE_TYPES_FIELD, mIncompatibleTypes);
             bundle.putStringArrayList(DELETED_TYPES_FIELD, mDeletedTypes);
@@ -264,6 +271,16 @@
             // AppSearchSession after we pass SetSchemaResponse via binder.
             return new SetSchemaResponse(bundle, mMigrationFailures);
         }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mMigrationFailures = new ArrayList<>(mMigrationFailures);
+                mDeletedTypes = new ArrayList<>(mDeletedTypes);
+                mMigratedTypes = new ArrayList<>(mMigratedTypes);
+                mIncompatibleTypes = new ArrayList<>(mIncompatibleTypes);
+                mBuilt = false;
+            }
+        }
     }
 
     /**
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java b/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
index 502b939..64d4828 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.os.Bundle;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Objects;
 
 /** The response class of {@code AppSearchSession#getStorageInfo}. */
@@ -74,39 +72,39 @@
 
     /** Builder for {@link StorageInfo} objects. */
     public static final class Builder {
-        private final Bundle mBundle = new Bundle();
-        private boolean mBuilt = false;
+        private long mSizeBytes;
+        private int mAliveDocumentsCount;
+        private int mAliveNamespacesCount;
 
         /** Sets the size in bytes. */
         @NonNull
         public StorageInfo.Builder setSizeBytes(long sizeBytes) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putLong(SIZE_BYTES_FIELD, sizeBytes);
+            mSizeBytes = sizeBytes;
             return this;
         }
 
         /** Sets the number of alive documents. */
         @NonNull
-        public StorageInfo.Builder setAliveDocumentsCount(int numAliveDocuments) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putInt(ALIVE_DOCUMENTS_COUNT, numAliveDocuments);
+        public StorageInfo.Builder setAliveDocumentsCount(int aliveDocumentsCount) {
+            mAliveDocumentsCount = aliveDocumentsCount;
             return this;
         }
 
         /** Sets the number of alive namespaces. */
         @NonNull
-        public StorageInfo.Builder setAliveNamespacesCount(int numAliveNamespaces) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putInt(ALIVE_NAMESPACES_COUNT, numAliveNamespaces);
+        public StorageInfo.Builder setAliveNamespacesCount(int aliveNamespacesCount) {
+            mAliveNamespacesCount = aliveNamespacesCount;
             return this;
         }
 
         /** Builds a {@link StorageInfo} object. */
         @NonNull
         public StorageInfo build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new StorageInfo(mBundle);
+            Bundle bundle = new Bundle();
+            bundle.putLong(SIZE_BYTES_FIELD, mSizeBytes);
+            bundle.putInt(ALIVE_DOCUMENTS_COUNT, mAliveDocumentsCount);
+            bundle.putInt(ALIVE_NAMESPACES_COUNT, mAliveNamespacesCount);
+            return new StorageInfo(bundle);
         }
     }
 }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
new file mode 100644
index 0000000..56a546a
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
@@ -0,0 +1,220 @@
+/*
+ * 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.stats;
+
+import android.annotation.NonNull;
+import android.app.appsearch.AppSearchResult;
+
+import java.util.Objects;
+
+/**
+ * Class holds detailed stats for {@link
+ * android.app.appsearch.AppSearchSession#setSchema(SetSchemaRequest)}.
+ *
+ * @hide
+ */
+public final class SetSchemaStats {
+    @NonNull private final String mPackageName;
+
+    @NonNull private final String mDatabase;
+
+    /**
+     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
+     * state.
+     */
+    @AppSearchResult.ResultCode private final int mStatusCode;
+
+    private final int mTotalLatencyMillis;
+
+    /** Overall time used for the native function call. */
+    private final int mNativeLatencyMillis;
+
+    /** Number of newly added schema types. */
+    private final int mNewTypeCount;
+
+    /** Number of deleted schema types. */
+    private final int mDeletedTypeCount;
+
+    /** Number of compatible schema type changes. */
+    private final int mCompatibleTypeChangeCount;
+
+    /** Number of index-incompatible schema type changes. */
+    private final int mIndexIncompatibleTypeChangeCount;
+
+    /** Number of backwards-incompatible schema type changes. */
+    private final int mBackwardsIncompatibleTypeChangeCount;
+
+    SetSchemaStats(@NonNull Builder builder) {
+        Objects.requireNonNull(builder);
+        mPackageName = builder.mPackageName;
+        mDatabase = builder.mDatabase;
+        mStatusCode = builder.mStatusCode;
+        mTotalLatencyMillis = builder.mTotalLatencyMillis;
+        mNativeLatencyMillis = builder.mNativeLatencyMillis;
+        mNewTypeCount = builder.mNewTypeCount;
+        mDeletedTypeCount = builder.mDeletedTypeCount;
+        mCompatibleTypeChangeCount = builder.mCompatibleTypeChangeCount;
+        mIndexIncompatibleTypeChangeCount = builder.mIndexIncompatibleTypeChangeCount;
+        mBackwardsIncompatibleTypeChangeCount = builder.mBackwardsIncompatibleTypeChangeCount;
+    }
+
+    /** Returns calling package name. */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /** Returns calling database name. */
+    @NonNull
+    public String getDatabase() {
+        return mDatabase;
+    }
+
+    /** Returns status of the SetSchema action. */
+    @AppSearchResult.ResultCode
+    public int getStatusCode() {
+        return mStatusCode;
+    }
+
+    /** Returns the total latency of the SetSchema action. */
+    public int getTotalLatencyMillis() {
+        return mTotalLatencyMillis;
+    }
+
+    /** Returns overall time used for the native function call. */
+    public int getNativeLatencyMillis() {
+        return mNativeLatencyMillis;
+    }
+
+    /** Returns number of newly added schema types. */
+    public int getNewTypeCount() {
+        return mNewTypeCount;
+    }
+
+    /** Returns number of deleted schema types. */
+    public int getDeletedTypeCount() {
+        return mDeletedTypeCount;
+    }
+
+    /** Returns number of compatible type changes. */
+    public int getCompatibleTypeChangeCount() {
+        return mCompatibleTypeChangeCount;
+    }
+
+    /**
+     * Returns number of index-incompatible type change.
+     *
+     * <p>An index-incompatible type change is one that affects how pre-existing data should be
+     * searched over, such as modifying the {@code IndexingType} of an existing property.
+     */
+    public int getIndexIncompatibleTypeChangeCount() {
+        return mIndexIncompatibleTypeChangeCount;
+    }
+
+    /**
+     * Returns number of backwards-incompatible type change.
+     *
+     * <p>For details on what constitutes a backward-incompatible type change, please see {@link
+     * android.app.appsearch.SetSchemaRequest}.
+     */
+    public int getBackwardsIncompatibleTypeChangeCount() {
+        return mBackwardsIncompatibleTypeChangeCount;
+    }
+
+    /** Builder for {@link SetSchemaStats}. */
+    public static class Builder {
+        @NonNull final String mPackageName;
+        @NonNull final String mDatabase;
+        @AppSearchResult.ResultCode int mStatusCode;
+        int mTotalLatencyMillis;
+        int mNativeLatencyMillis;
+        int mNewTypeCount;
+        int mDeletedTypeCount;
+        int mCompatibleTypeChangeCount;
+        int mIndexIncompatibleTypeChangeCount;
+        int mBackwardsIncompatibleTypeChangeCount;
+
+        /** Constructor for the {@link Builder}. */
+        public Builder(@NonNull String packageName, @NonNull String database) {
+            mPackageName = Objects.requireNonNull(packageName);
+            mDatabase = Objects.requireNonNull(database);
+        }
+
+        /** Sets the status of the SetSchema action. */
+        @NonNull
+        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
+            mStatusCode = statusCode;
+            return this;
+        }
+
+        /** Sets total latency for the SetSchema action. */
+        @NonNull
+        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
+            mTotalLatencyMillis = totalLatencyMillis;
+            return this;
+        }
+
+        /** Sets native latency in milliseconds. */
+        @NonNull
+        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
+            mNativeLatencyMillis = nativeLatencyMillis;
+            return this;
+        }
+
+        /** Sets number of new types. */
+        @NonNull
+        public Builder setNewTypeCount(int newTypeCount) {
+            mNewTypeCount = newTypeCount;
+            return this;
+        }
+
+        /** Sets number of deleted types. */
+        @NonNull
+        public Builder setDeletedTypeCount(int deletedTypeCount) {
+            mDeletedTypeCount = deletedTypeCount;
+            return this;
+        }
+
+        /** Sets number of compatible type changes. */
+        @NonNull
+        public Builder setCompatibleTypeChangeCount(int compatibleTypeChangeCount) {
+            mCompatibleTypeChangeCount = compatibleTypeChangeCount;
+            return this;
+        }
+
+        /** Sets number of index-incompatible type changes. */
+        @NonNull
+        public Builder setIndexIncompatibleTypeChangeCount(int indexIncompatibleTypeChangeCount) {
+            mIndexIncompatibleTypeChangeCount = indexIncompatibleTypeChangeCount;
+            return this;
+        }
+
+        /** Sets number of backwards-incompatible type changes. */
+        @NonNull
+        public Builder setBackwardsIncompatibleTypeChangeCount(
+                int backwardsIncompatibleTypeChangeCount) {
+            mBackwardsIncompatibleTypeChangeCount = backwardsIncompatibleTypeChangeCount;
+            return this;
+        }
+
+        /** Builds a new {@link SetSchemaStats} from the {@link Builder}. */
+        @NonNull
+        public SetSchemaStats build() {
+            return new SetSchemaStats(/* builder= */ this);
+        }
+    }
+}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 277740f..d07a3b9 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-Ic6be29e84e7c6f31cdae37973850bb3395920326
+Ibbf4260deb720ce724be81ee4394ea96181ee0f7
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java
index 845274d..d28d4ac 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java
@@ -165,43 +165,37 @@
         /** Sets the from address of {@link AppSearchEmail} */
         @NonNull
         public Builder setFrom(@NonNull String from) {
-            setPropertyString(KEY_FROM, from);
-            return this;
+            return setPropertyString(KEY_FROM, from);
         }
 
         /** Sets the destination address of {@link AppSearchEmail} */
         @NonNull
         public Builder setTo(@NonNull String... to) {
-            setPropertyString(KEY_TO, to);
-            return this;
+            return setPropertyString(KEY_TO, to);
         }
 
         /** Sets the CC list of {@link AppSearchEmail} */
         @NonNull
         public Builder setCc(@NonNull String... cc) {
-            setPropertyString(KEY_CC, cc);
-            return this;
+            return setPropertyString(KEY_CC, cc);
         }
 
         /** Sets the BCC list of {@link AppSearchEmail} */
         @NonNull
         public Builder setBcc(@NonNull String... bcc) {
-            setPropertyString(KEY_BCC, bcc);
-            return this;
+            return setPropertyString(KEY_BCC, bcc);
         }
 
         /** Sets the subject of {@link AppSearchEmail} */
         @NonNull
         public Builder setSubject(@NonNull String subject) {
-            setPropertyString(KEY_SUBJECT, subject);
-            return this;
+            return setPropertyString(KEY_SUBJECT, subject);
         }
 
         /** Sets the body of {@link AppSearchEmail} */
         @NonNull
         public Builder setBody(@NonNull String body) {
-            setPropertyString(KEY_BODY, body);
-            return this;
+            return setPropertyString(KEY_BODY, body);
         }
 
         /** Builds the {@link AppSearchEmail} object. */
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 01f31e4..b096537 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -138,6 +139,36 @@
     public static final String ACTION_NEXT_ALARM_CLOCK_CHANGED =
             "android.app.action.NEXT_ALARM_CLOCK_CHANGED";
 
+    /**
+     * Broadcast Action: An app is granted the
+     * {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} permission.
+     *
+     * <p>When the user revokes the {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM}
+     * permission, all alarms scheduled with
+     * {@link #setExact}, {@link #setExactAndAllowWhileIdle} and
+     * {@link #setAlarmClock(AlarmClockInfo, PendingIntent)} will be deleted.
+     *
+     * <p>When the user grants the {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM},
+     * this broadcast will be sent. Applications can reschedule all the necessary alarms when
+     * receiving it.
+     *
+     * <p><em>Note:</em>
+     * Applications are still required to check {@link #canScheduleExactAlarms()}
+     * before using the above APIs after receiving this broadcast,
+     * because it's possible that the permission is already revoked again by the time
+     * applications receive this broadcast.
+     *
+     * <p>This broadcast will be sent to both runtime receivers and manifest receivers.
+     *
+     * <p>This broadcast is sent as a foreground broadcast.
+     * See {@link android.content.Intent#FLAG_RECEIVER_FOREGROUND}.
+     *
+     * <p>When an application receives this broadcast, it's allowed to start a foreground service.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED =
+            "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
+
     /** @hide */
     @UnsupportedAppUsage
     public static final long WINDOW_EXACT = 0;
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index b62ece6..9dd1296 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -251,6 +251,12 @@
      * @hide
      */
     public static final int REASON_LOCALE_CHANGED = 206;
+    /**
+     * Broadcast
+     * {@link android.app.AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED}
+     * @hide
+     */
+    public static final int REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = 207;
     /* Reason code range 300-399 are reserved for other internal reasons */
     /**
      * Device idle system allow list, including EXCEPT-IDLE
@@ -386,6 +392,7 @@
             REASON_TIMEZONE_CHANGED,
             REASON_TIME_CHANGED,
             REASON_LOCALE_CHANGED,
+            REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
             REASON_SYSTEM_ALLOW_LISTED,
             REASON_ALARM_MANAGER_ALARM_CLOCK,
             REASON_ALARM_MANAGER_WHILE_IDLE,
@@ -664,6 +671,8 @@
                 return "TIME_CHANGED";
             case REASON_LOCALE_CHANGED:
                 return "LOCALE_CHANGED";
+            case REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED:
+                return "REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
             case REASON_SYSTEM_ALLOW_LISTED:
                 return "SYSTEM_ALLOW_LISTED";
             case REASON_ALARM_MANAGER_ALARM_CLOCK:
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index b3396c5..0eb2609 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -30,6 +30,7 @@
 import static android.app.AlarmManager.RTC;
 import static android.app.AlarmManager.RTC_WAKEUP;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+import static android.os.PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED;
 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE;
 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -1704,6 +1705,11 @@
                                 if (!hasScheduleExactAlarmInternal(packageName, uid)) {
                                     mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS,
                                             uid, 0, packageName).sendToTarget();
+                                } else {
+                                    // TODO(b/187206399) Make sure this won't be sent, if the app
+                                    // already had the appop previously.
+                                    sendScheduleExactAlarmPermissionStateChangedBroadcast(
+                                            packageName, UserHandle.getUserId(uid));
                                 }
                             }
                         });
@@ -4816,6 +4822,30 @@
         }
     }
 
+    /**
+     * Send {@link AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED} to
+     * the app that is just granted the permission.
+     */
+    private void sendScheduleExactAlarmPermissionStateChangedBroadcast(
+            String packageName, int userId) {
+        final Intent i = new Intent(
+                AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED);
+        i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+                | Intent.FLAG_RECEIVER_FOREGROUND);
+        i.setPackage(packageName);
+
+        // We need to allow the app to start a foreground service.
+        // This broadcast is very rare, so we do not cache the BroadcastOptions.
+        final BroadcastOptions opts = BroadcastOptions.makeBasic();
+        opts.setTemporaryAppAllowlist(
+                mActivityManagerInternal.getBootTimeTempAllowListDuration(),
+                TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+                REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, "");
+        getContext().sendBroadcastAsUser(i, UserHandle.of(userId), /*permission*/ null,
+                opts.toBundle());
+    }
+
     private void decrementAlarmCount(int uid, int decrement) {
         int oldCount = 0;
         final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 2be8264..1e72ddf 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -555,7 +555,7 @@
 
             // Start the process
             final Process process = new ProcessBuilder()
-                    .command("logcat", "-d", "-v threadtime,uid", "-T", timestamp)
+                    .command("logcat", "-d", "-v", "threadtime,uid", "-T", timestamp)
                     .start();
 
             // Nothing to write. Don't let the command accidentally block.
diff --git a/core/api/current.txt b/core/api/current.txt
index de92fd1..9131816 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4404,6 +4404,7 @@
     method public void setWindow(int, long, long, android.app.PendingIntent);
     method public void setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler);
     field public static final String ACTION_NEXT_ALARM_CLOCK_CHANGED = "android.app.action.NEXT_ALARM_CLOCK_CHANGED";
+    field public static final String ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
     field public static final int ELAPSED_REALTIME = 3; // 0x3
     field public static final int ELAPSED_REALTIME_WAKEUP = 2; // 0x2
     field public static final long INTERVAL_DAY = 86400000L; // 0x5265c00L
@@ -24710,32 +24711,37 @@
     method @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) public int getSubErrorCode();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.PlaybackErrorEvent> CREATOR;
-    field public static final int ERROR_AUDIOTRACK_INIT = 17; // 0x11
-    field public static final int ERROR_AUDIOTRACK_OTHER = 19; // 0x13
-    field public static final int ERROR_AUDIOTRACK_WRITE = 18; // 0x12
-    field public static final int ERROR_DECODER_DECODE = 14; // 0xe
-    field public static final int ERROR_DECODER_INIT = 13; // 0xd
-    field public static final int ERROR_DECODER_OOM = 15; // 0xf
-    field public static final int ERROR_DECODER_OTHER = 16; // 0x10
+    field public static final int ERROR_AUDIO_TRACK_INIT_FAILED = 17; // 0x11
+    field public static final int ERROR_AUDIO_TRACK_OTHER = 19; // 0x13
+    field public static final int ERROR_AUDIO_TRACK_WRITE_FAILED = 18; // 0x12
+    field public static final int ERROR_DECODER_INIT_FAILED = 13; // 0xd
+    field public static final int ERROR_DECODING_FAILED = 14; // 0xe
+    field public static final int ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES = 15; // 0xf
+    field public static final int ERROR_DECODING_FORMAT_UNSUPPORTED = 35; // 0x23
+    field public static final int ERROR_DECODING_OTHER = 16; // 0x10
     field public static final int ERROR_DRM_CONTENT_ERROR = 28; // 0x1c
-    field public static final int ERROR_DRM_DISALLOWED = 26; // 0x1a
-    field public static final int ERROR_DRM_LICENSE_ERROR = 25; // 0x19
+    field public static final int ERROR_DRM_DEVICE_REVOKED = 29; // 0x1d
+    field public static final int ERROR_DRM_DISALLOWED_OPERATION = 26; // 0x1a
+    field public static final int ERROR_DRM_LICENSE_ACQUISITION_FAILED = 25; // 0x19
     field public static final int ERROR_DRM_OTHER = 30; // 0x1e
     field public static final int ERROR_DRM_PROVISIONING_FAILED = 24; // 0x18
-    field public static final int ERROR_DRM_REVOKED = 29; // 0x1d
+    field public static final int ERROR_DRM_SCHEME_UNSUPPORTED = 23; // 0x17
     field public static final int ERROR_DRM_SYSTEM_ERROR = 27; // 0x1b
-    field public static final int ERROR_DRM_UNAVAILABLE = 23; // 0x17
-    field public static final int ERROR_MEDIA_MANIFEST = 10; // 0xa
-    field public static final int ERROR_MEDIA_OTHER = 12; // 0xc
-    field public static final int ERROR_MEDIA_PARSER = 11; // 0xb
-    field public static final int ERROR_NETWORK_BAD_STATUS = 5; // 0x5
-    field public static final int ERROR_NETWORK_CLOSED = 8; // 0x8
-    field public static final int ERROR_NETWORK_CONNECT = 4; // 0x4
-    field public static final int ERROR_NETWORK_DNS = 6; // 0x6
-    field public static final int ERROR_NETWORK_OFFLINE = 3; // 0x3
-    field public static final int ERROR_NETWORK_OTHER = 9; // 0x9
-    field public static final int ERROR_NETWORK_TIMEOUT = 7; // 0x7
+    field public static final int ERROR_IO_BAD_HTTP_STATUS = 5; // 0x5
+    field public static final int ERROR_IO_CONNECTION_CLOSED = 8; // 0x8
+    field public static final int ERROR_IO_CONNECTION_TIMEOUT = 7; // 0x7
+    field public static final int ERROR_IO_DNS_FAILED = 6; // 0x6
+    field public static final int ERROR_IO_FILE_NOT_FOUND = 31; // 0x1f
+    field public static final int ERROR_IO_NETWORK_CONNECTION_FAILED = 4; // 0x4
+    field public static final int ERROR_IO_NETWORK_UNAVAILABLE = 3; // 0x3
+    field public static final int ERROR_IO_NO_PERMISSION = 32; // 0x20
+    field public static final int ERROR_IO_OTHER = 9; // 0x9
     field public static final int ERROR_OTHER = 1; // 0x1
+    field public static final int ERROR_PARSING_CONTAINER_MALFORMED = 11; // 0xb
+    field public static final int ERROR_PARSING_CONTAINER_UNSUPPORTED = 34; // 0x22
+    field public static final int ERROR_PARSING_MANIFEST_MALFORMED = 10; // 0xa
+    field public static final int ERROR_PARSING_MANIFEST_UNSUPPORTED = 33; // 0x21
+    field public static final int ERROR_PARSING_OTHER = 12; // 0xc
     field public static final int ERROR_PLAYER_BEHIND_LIVE_WINDOW = 21; // 0x15
     field public static final int ERROR_PLAYER_OTHER = 22; // 0x16
     field public static final int ERROR_PLAYER_REMOTE = 20; // 0x14
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
index ad90364..e90bf86 100644
--- a/core/java/android/app/Presentation.java
+++ b/core/java/android/app/Presentation.java
@@ -37,7 +37,8 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams.WindowType;
 
-import com.android.internal.util.Preconditions;
+import java.util.Objects;
+
 /**
  * Base class for presentations.
  * <p>
@@ -153,7 +154,7 @@
 
     private final Display mDisplay;
     private final DisplayManager mDisplayManager;
-    private final Handler mHandler = new Handler(Preconditions.checkNotNull(Looper.myLooper(),
+    private final Handler mHandler = new Handler(Objects.requireNonNull(Looper.myLooper(),
             "Presentation must be constructed on a looper thread."));
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 0ca6d74..4032663 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1770,13 +1770,13 @@
      *
      * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
      * with the UUIDs supported by the remote end. If there is an error
-     * in getting the SDP records or if the process takes a long time,
-     * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
-     * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
+     * in getting the SDP records or if the process takes a long time, or the device is bonding and
+     * we have its UUIDs cached, {@link #ACTION_UUID} intent is sent with the UUIDs that is
+     * currently present in the cache. Clients should use the {@link #getUuids} to get UUIDs
      * if service discovery is not to be performed.
      *
      * @return False if the check fails, True if the process of initiating an ACL connection
-     * to the remote device was started.
+     * to the remote device was started or cached UUIDs will be broadcast.
      */
     @RequiresLegacyBluetoothPermission
     @RequiresBluetoothConnectPermission
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 98acd98..01d1aa5 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -79,6 +79,16 @@
     public static final int DIRECTION_OUT = 1;
 
     /**
+     * Used when applying a transform to direct traffic through an {@link IpSecTransform} for
+     * forwarding between interfaces.
+     *
+     * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
+     *
+     * @hide
+     */
+    public static final int DIRECTION_FWD = 2;
+
+    /**
      * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
      *
      * <p>No IPsec packet may contain an SPI of 0.
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
index 5e93820..14e70cf 100644
--- a/core/java/android/net/vcn/VcnNetworkPolicyResult.java
+++ b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
@@ -87,6 +87,16 @@
                 && mNetworkCapabilities.equals(that.mNetworkCapabilities);
     }
 
+    @Override
+    public String toString() {
+        return "VcnNetworkPolicyResult { "
+                + "mIsTeardownRequested = "
+                + mIsTearDownRequested
+                + ", mNetworkCapabilities"
+                + mNetworkCapabilities
+                + " }";
+    }
+
     /** {@inheritDoc} */
     @Override
     public int describeContents() {
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
index b47d564..b0d4f3b 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
@@ -85,6 +85,11 @@
         return mVcnNetworkPolicyResult.equals(that.mVcnNetworkPolicyResult);
     }
 
+    @Override
+    public String toString() {
+        return mVcnNetworkPolicyResult.toString();
+    }
+
     /** {@inheritDoc} */
     @Override
     public int describeContents() {
diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java
index 449e3ae..ee86265 100644
--- a/core/java/android/os/AggregateBatteryConsumer.java
+++ b/core/java/android/os/AggregateBatteryConsumer.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 
+import java.io.PrintWriter;
+
 /**
  * Contains power consumption data across the entire device.
  *
@@ -38,6 +40,11 @@
     }
 
     @Override
+    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
+        mPowerComponents.dump(pw, skipEmptyComponents);
+    }
+
+    @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         super.writeToParcel(dest, flags);
         dest.writeDouble(mConsumedPowerMah);
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index 6b628b0..edb30b0 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -27,7 +28,7 @@
  *
  * @hide
  */
-public class BatteryConsumer {
+public abstract class BatteryConsumer {
 
     /**
      * Power usage component, describing the particular part of the system
@@ -85,12 +86,37 @@
     public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
     public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
 
+    private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT];
+
+    static {
+        // Assign individually to avoid future mismatch
+        sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen";
+        sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu";
+        sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth";
+        sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera";
+        sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio";
+        sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video";
+        sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight";
+        sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services";
+        sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio";
+        sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors";
+        sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss";
+        sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi";
+        sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock";
+        sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory";
+        sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone";
+        sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display";
+        sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle";
+        sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed";
+    }
+
     /**
      * Identifiers of models used for power estimation.
      *
      * @hide
      */
     @IntDef(prefix = {"POWER_MODEL_"}, value = {
+            POWER_MODEL_UNDEFINED,
             POWER_MODEL_POWER_PROFILE,
             POWER_MODEL_MEASURED_ENERGY,
     })
@@ -99,15 +125,20 @@
     }
 
     /**
+     * Unspecified power model.
+     */
+    public static final int POWER_MODEL_UNDEFINED = 0;
+
+    /**
      * Power model that is based on average consumption rates that hardware components
      * consume in various states.
      */
-    public static final int POWER_MODEL_POWER_PROFILE = 0;
+    public static final int POWER_MODEL_POWER_PROFILE = 1;
 
     /**
      * Power model that is based on energy consumption measured by on-device power monitors.
      */
-    public static final int POWER_MODEL_MEASURED_ENERGY = 1;
+    public static final int POWER_MODEL_MEASURED_ENERGY = 2;
 
     protected final PowerComponents mPowerComponents;
 
@@ -197,6 +228,41 @@
         mPowerComponents.writeToParcel(dest, flags);
     }
 
+    /**
+     * Returns the name of the specified component.  Intended for logging and debugging.
+     */
+    public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) {
+        return sPowerComponentNames[componentId];
+    }
+
+    /**
+     * Returns the name of the specified power model.  Intended for logging and debugging.
+     */
+    public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) {
+        switch (powerModel) {
+            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
+                return "measured energy";
+            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
+                return "power profile";
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * Prints the stats in a human-readable format.
+     */
+    public void dump(PrintWriter pw) {
+        dump(pw, true);
+    }
+
+    /**
+     * Prints the stats in a human-readable format.
+     *
+     * @param skipEmptyComponents if true, omit any power components with a zero amount.
+     */
+    public abstract void dump(PrintWriter pw, boolean skipEmptyComponents);
+
     protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
         final PowerComponents.Builder mPowerComponentsBuilder;
 
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index eec6810..c97d1f8 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -51,6 +51,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
+import com.android.internal.os.BatteryUsageStatsProvider;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -5299,154 +5300,19 @@
         pw.println(getDischargeAmountScreenDozeSinceCharge());
         pw.println();
 
+        final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
+        final BatteryUsageStats stats = provider.getBatteryUsageStats(
+                new BatteryUsageStatsQuery.Builder()
+                        .setMaxStatsAgeMs(0)
+                        .includePowerModels()
+                        .build());
+        stats.dump(pw, prefix);
+
         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
         helper.create(this);
         helper.refreshStats(which, UserHandle.USER_ALL);
-        List<BatterySipper> sippers = helper.getUsageList();
-        if (sippers != null && sippers.size() > 0) {
-            pw.print(prefix); pw.println("  Estimated power use (mAh):");
-            pw.print(prefix); pw.print("    Capacity: ");
-                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
-                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
-                    pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
-                    if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
-                        pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
-                    }
-                    pw.println();
-            for (int i=0; i<sippers.size(); i++) {
-                final BatterySipper bs = sippers.get(i);
-                pw.print(prefix);
-                switch (bs.drainType) {
-                    case AMBIENT_DISPLAY:
-                        pw.print("    Ambient display: ");
-                        break;
-                    case IDLE:
-                        pw.print("    Idle: ");
-                        break;
-                    case CELL:
-                        pw.print("    Cell standby: ");
-                        break;
-                    case PHONE:
-                        pw.print("    Phone calls: ");
-                        break;
-                    case WIFI:
-                        pw.print("    Wifi: ");
-                        break;
-                    case BLUETOOTH:
-                        pw.print("    Bluetooth: ");
-                        break;
-                    case SCREEN:
-                        pw.print("    Screen: ");
-                        break;
-                    case FLASHLIGHT:
-                        pw.print("    Flashlight: ");
-                        break;
-                    case APP:
-                        pw.print("    Uid ");
-                        UserHandle.formatUid(pw, bs.uidObj.getUid());
-                        pw.print(": ");
-                        break;
-                    case USER:
-                        pw.print("    User "); pw.print(bs.userId);
-                        pw.print(": ");
-                        break;
-                    case UNACCOUNTED:
-                        pw.print("    Unaccounted: ");
-                        break;
-                    case OVERCOUNTED:
-                        pw.print("    Over-counted: ");
-                        break;
-                    case CAMERA:
-                        pw.print("    Camera: ");
-                        break;
-                    default:
-                        pw.print("    ???: ");
-                        break;
-                }
-                printmAh(pw, bs.totalPowerMah);
 
-                if (bs.usagePowerMah != bs.totalPowerMah) {
-                    // If the usage (generic power) isn't the whole amount, we list out
-                    // what components are involved in the calculation.
-
-                    pw.print(" (");
-                    if (bs.usagePowerMah != 0) {
-                        pw.print(" usage=");
-                        printmAh(pw, bs.usagePowerMah);
-                    }
-                    if (bs.cpuPowerMah != 0) {
-                        pw.print(" cpu=");
-                        printmAh(pw, bs.cpuPowerMah);
-                    }
-                    if (bs.wakeLockPowerMah != 0) {
-                        pw.print(" wake=");
-                        printmAh(pw, bs.wakeLockPowerMah);
-                    }
-                    if (bs.mobileRadioPowerMah != 0) {
-                        pw.print(" radio=");
-                        printmAh(pw, bs.mobileRadioPowerMah);
-                    }
-                    if (bs.wifiPowerMah != 0) {
-                        pw.print(" wifi=");
-                        printmAh(pw, bs.wifiPowerMah);
-                    }
-                    if (bs.bluetoothPowerMah != 0) {
-                        pw.print(" bt=");
-                        printmAh(pw, bs.bluetoothPowerMah);
-                    }
-                    if (bs.gpsPowerMah != 0) {
-                        pw.print(" gps=");
-                        printmAh(pw, bs.gpsPowerMah);
-                    }
-                    if (bs.sensorPowerMah != 0) {
-                        pw.print(" sensor=");
-                        printmAh(pw, bs.sensorPowerMah);
-                    }
-                    if (bs.cameraPowerMah != 0) {
-                        pw.print(" camera=");
-                        printmAh(pw, bs.cameraPowerMah);
-                    }
-                    if (bs.flashlightPowerMah != 0) {
-                        pw.print(" flash=");
-                        printmAh(pw, bs.flashlightPowerMah);
-                    }
-                    if (bs.customMeasuredPowerMah != null) {
-                        for (int idx = 0; idx < bs.customMeasuredPowerMah.length; idx++) {
-                            final double customPowerMah = bs.customMeasuredPowerMah[idx];
-                            if (customPowerMah != 0) {
-                                pw.print(" custom[" + idx + "]=");
-                                printmAh(pw, customPowerMah);
-                            }
-                        }
-                    }
-                    pw.print(" )");
-                }
-
-                // If there is additional smearing information, include it.
-                if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
-                    pw.print(" Including smearing: ");
-                    printmAh(pw, bs.totalSmearedPowerMah);
-                    pw.print(" (");
-                    if (bs.screenPowerMah != 0) {
-                        pw.print(" screen=");
-                        printmAh(pw, bs.screenPowerMah);
-                    }
-                    if (bs.proportionalSmearMah != 0) {
-                        pw.print(" proportional=");
-                        printmAh(pw, bs.proportionalSmearMah);
-                    }
-                    pw.print(" )");
-                }
-                if (bs.shouldHide) {
-                    pw.print(" Excluded from smearing");
-                }
-
-                pw.println();
-            }
-            pw.println();
-        }
-
-        sippers = helper.getMobilemsppList();
+        final List<BatterySipper> sippers = helper.getMobilemsppList();
         if (sippers != null && sippers.size() > 0) {
             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
             long totalTime = 0;
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 6bc861f..3225667 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -23,10 +23,13 @@
 
 import com.android.internal.os.BatteryStatsHistory;
 import com.android.internal.os.BatteryStatsHistoryIterator;
+import com.android.internal.os.PowerCalculator;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -73,6 +76,7 @@
 
     private final int mDischargePercentage;
     private final long mStatsStartTimestampMs;
+    private final double mBatteryCapacityMah;
     private final double mDischargedPowerLowerBound;
     private final double mDischargedPowerUpperBound;
     private final long mBatteryTimeRemainingMs;
@@ -86,6 +90,7 @@
 
     private BatteryUsageStats(@NonNull Builder builder) {
         mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
+        mBatteryCapacityMah = builder.mBatteryCapacityMah;
         mDischargePercentage = builder.mDischargePercentage;
         mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
         mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
@@ -145,6 +150,13 @@
     }
 
     /**
+     * Returns battery capacity in milli-amp-hours.
+     */
+    public double getBatteryCapacity() {
+        return mBatteryCapacityMah;
+    }
+
+    /**
      * Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
      * charged), as percentage of the full charge in the range [0:100]
      */
@@ -217,6 +229,7 @@
 
     private BatteryUsageStats(@NonNull Parcel source) {
         mStatsStartTimestampMs = source.readLong();
+        mBatteryCapacityMah = source.readDouble();
         mDischargePercentage = source.readInt();
         mDischargedPowerLowerBound = source.readDouble();
         mDischargedPowerUpperBound = source.readDouble();
@@ -274,6 +287,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeLong(mStatsStartTimestampMs);
+        dest.writeDouble(mBatteryCapacityMah);
         dest.writeInt(mDischargePercentage);
         dest.writeDouble(mDischargedPowerLowerBound);
         dest.writeDouble(mDischargedPowerUpperBound);
@@ -322,6 +336,104 @@
     };
 
     /**
+     * Prints the stats in a human-readable format.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix);
+        pw.println("  Estimated power use (mAh):");
+        pw.print(prefix);
+        pw.print("    Capacity: ");
+        PowerCalculator.printPowerMah(pw, getBatteryCapacity());
+        pw.print(", Computed drain: ");
+        PowerCalculator.printPowerMah(pw, getConsumedPower());
+        final Range<Double> dischargedPowerRange = getDischargedPowerRange();
+        pw.print(", actual drain: ");
+        PowerCalculator.printPowerMah(pw, dischargedPowerRange.getLower());
+        if (!dischargedPowerRange.getLower().equals(dischargedPowerRange.getUpper())) {
+            pw.print("-");
+            PowerCalculator.printPowerMah(pw, dischargedPowerRange.getUpper());
+        }
+        pw.println();
+
+        pw.println("    Global");
+        final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer(
+                AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+        final BatteryConsumer appsConsumer = getAggregateBatteryConsumer(
+                AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+
+        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+                componentId++) {
+            final double devicePowerMah = deviceConsumer.getConsumedPower(componentId);
+            final double appsPowerMah = appsConsumer.getConsumedPower(componentId);
+            if (devicePowerMah == 0 && appsPowerMah == 0) {
+                continue;
+            }
+
+            final String componentName = BatteryConsumer.powerComponentIdToString(componentId);
+            printPowerComponent(pw, prefix, componentName, devicePowerMah, appsPowerMah,
+                    deviceConsumer.getPowerModel(componentId),
+                    deviceConsumer.getUsageDurationMillis(componentId));
+        }
+
+        for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+                componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                        + mCustomPowerComponentNames.length;
+                componentId++) {
+            final double devicePowerMah =
+                    deviceConsumer.getConsumedPowerForCustomComponent(componentId);
+            final double appsPowerMah =
+                    appsConsumer.getConsumedPowerForCustomComponent(componentId);
+            if (devicePowerMah == 0 && appsPowerMah == 0) {
+                continue;
+            }
+
+            printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId),
+                    devicePowerMah, appsPowerMah,
+                    BatteryConsumer.POWER_MODEL_UNDEFINED,
+                    deviceConsumer.getUsageDurationForCustomComponentMillis(componentId));
+        }
+
+        dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers());
+        dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers());
+    }
+
+    private void printPowerComponent(PrintWriter pw, String prefix, String componentName,
+            double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(prefix).append("      ").append(componentName).append(": ")
+                .append(PowerCalculator.formatCharge(devicePowerMah));
+        if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED
+                && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
+            sb.append(" [");
+            sb.append(BatteryConsumer.powerModelToString(powerModel));
+            sb.append("]");
+        }
+        sb.append(" apps: ").append(PowerCalculator.formatCharge(appsPowerMah));
+        if (durationMs != 0) {
+            sb.append(" duration: ");
+            BatteryStats.formatTimeMs(sb, durationMs);
+        }
+
+        pw.println(sb.toString());
+    }
+
+    private void dumpSortedBatteryConsumers(PrintWriter pw, String prefix,
+            List<? extends BatteryConsumer> batteryConsumers) {
+        batteryConsumers.sort(
+                Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower)
+                        .reversed());
+        for (BatteryConsumer consumer : batteryConsumers) {
+            if (consumer.getConsumedPower() == 0) {
+                continue;
+            }
+            pw.print(prefix);
+            pw.print("    ");
+            consumer.dump(pw);
+            pw.println();
+        }
+    }
+
+    /**
      * Builder for BatteryUsageStats.
      */
     public static final class Builder {
@@ -329,6 +441,7 @@
         private final String[] mCustomPowerComponentNames;
         private final boolean mIncludePowerModels;
         private long mStatsStartTimestampMs;
+        private double mBatteryCapacityMah;
         private int mDischargePercentage;
         private double mDischargedPowerLowerBoundMah;
         private double mDischargedPowerUpperBoundMah;
@@ -365,6 +478,14 @@
         }
 
         /**
+         * Sets the battery capacity in milli-amp-hours.
+         */
+        public Builder setBatteryCapacity(double batteryCapacityMah) {
+            mBatteryCapacityMah = batteryCapacityMah;
+            return this;
+        }
+
+        /**
          * Sets the timestamp of the latest battery stats reset, in milliseconds.
          */
         public Builder setStatsStartTimestamp(long statsStartTimestampMs) {
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index 47a2edc..964f1b6 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -17,6 +17,10 @@
 
 import android.annotation.NonNull;
 
+import com.android.internal.os.PowerCalculator;
+
+import java.io.PrintWriter;
+
 /**
  * Contains details of battery attribution data broken down to individual power drain types
  * such as CPU, RAM, GPU etc.
@@ -202,6 +206,37 @@
         return max;
     }
 
+    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
+        String separator = "";
+        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+                componentId++) {
+            final double componentPower = getConsumedPower(componentId);
+            if (skipEmptyComponents && componentPower == 0) {
+                continue;
+            }
+            pw.print(separator); separator = " ";
+            pw.print(BatteryConsumer.powerComponentIdToString(componentId));
+            pw.print("=");
+            PowerCalculator.printPowerMah(pw, componentPower);
+        }
+
+        final int customComponentCount = getCustomPowerComponentCount();
+        for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+                customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                        + customComponentCount;
+                customComponentId++) {
+            final double customComponentPower =
+                    getConsumedPowerForCustomComponent(customComponentId);
+            if (skipEmptyComponents && customComponentPower == 0) {
+                continue;
+            }
+            pw.print(separator); separator = " ";
+            pw.print(getCustomPowerComponentName(customComponentId));
+            pw.print("=");
+            PowerCalculator.printPowerMah(pw, customComponentPower);
+        }
+    }
+
     /**
      * Builder for PowerComponents.
      */
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index b1fb570..16a6c76 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -20,6 +20,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
+import com.android.internal.os.PowerCalculator;
+
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -112,6 +115,18 @@
         dest.writeLong(mTimeInBackgroundMs);
     }
 
+    @Override
+    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
+        final double consumedPower = getConsumedPower();
+        pw.print("UID ");
+        UserHandle.formatUid(pw, getUid());
+        pw.print(": ");
+        PowerCalculator.printPowerMah(pw, consumedPower);
+        pw.print(" ( ");
+        mPowerComponents.dump(pw, skipEmptyComponents  /* skipTotalPowerComponent */);
+        pw.print(" ) ");
+    }
+
     @NonNull
     public static final Creator<UidBatteryConsumer> CREATOR = new Creator<UidBatteryConsumer>() {
         public UidBatteryConsumer createFromParcel(@NonNull Parcel source) {
diff --git a/core/java/android/os/UserBatteryConsumer.java b/core/java/android/os/UserBatteryConsumer.java
index d0d0d38..429d2c5 100644
--- a/core/java/android/os/UserBatteryConsumer.java
+++ b/core/java/android/os/UserBatteryConsumer.java
@@ -18,6 +18,9 @@
 
 import android.annotation.NonNull;
 
+import com.android.internal.os.PowerCalculator;
+
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -52,6 +55,18 @@
         dest.writeInt(mUserId);
     }
 
+    @Override
+    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
+        final double consumedPower = getConsumedPower();
+        pw.print("User ");
+        pw.print(mUserId);
+        pw.print(": ");
+        PowerCalculator.printPowerMah(pw, consumedPower);
+        pw.print(" ( ");
+        mPowerComponents.dump(pw, skipEmptyComponents  /* skipTotalPowerComponent */);
+        pw.print(" ) ");
+    }
+
     public static final Creator<UserBatteryConsumer> CREATOR =
             new Creator<UserBatteryConsumer>() {
                 @Override
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c51c506..3bdc546 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8545,9 +8545,10 @@
                 "one_handed_tutorial_show_count";
 
         /**
-         * Indicates whether ui translation is enabled.
+         * Toggle to enable/disable for the apps to use the Ui translation for Views. The value
+         * indicates whether the Ui translation is enabled by the user.
          * <p>
-         * Type: int (0 for false, 1 for true)
+         * Type: {@code int} ({@code 0} for disabled, {@code 1} for enabled)
          *
          * @hide
          */
diff --git a/core/java/android/window/PictureInPictureSurfaceTransaction.java b/core/java/android/window/PictureInPictureSurfaceTransaction.java
index 96a8ac8..dbf7eb3 100644
--- a/core/java/android/window/PictureInPictureSurfaceTransaction.java
+++ b/core/java/android/window/PictureInPictureSurfaceTransaction.java
@@ -24,6 +24,7 @@
 import android.os.Parcelable;
 import android.view.SurfaceControl;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -37,10 +38,11 @@
     public final float mPositionX;
     public final float mPositionY;
 
-    public final float mScaleX;
-    public final float mScaleY;
+    public final float[] mFloat9;
 
+    // Though this can be determined by mFloat9, it's easier to set the value directly
     public final float mRotation;
+
     public final float mCornerRadius;
 
     private final Rect mWindowCrop = new Rect();
@@ -48,21 +50,19 @@
     public PictureInPictureSurfaceTransaction(Parcel in) {
         mPositionX = in.readFloat();
         mPositionY = in.readFloat();
-        mScaleX = in.readFloat();
-        mScaleY = in.readFloat();
+        mFloat9 = new float[9];
+        in.readFloatArray(mFloat9);
         mRotation = in.readFloat();
         mCornerRadius = in.readFloat();
         mWindowCrop.set(Objects.requireNonNull(in.readTypedObject(Rect.CREATOR)));
     }
 
     public PictureInPictureSurfaceTransaction(float positionX, float positionY,
-            float scaleX, float scaleY,
-            float rotation, float cornerRadius,
+            float[] float9, float rotation, float cornerRadius,
             @Nullable Rect windowCrop) {
         mPositionX = positionX;
         mPositionY = positionY;
-        mScaleX = scaleX;
-        mScaleY = scaleY;
+        mFloat9 = Arrays.copyOf(float9, 9);
         mRotation = rotation;
         mCornerRadius = cornerRadius;
         if (windowCrop != null) {
@@ -72,13 +72,14 @@
 
     public PictureInPictureSurfaceTransaction(PictureInPictureSurfaceTransaction other) {
         this(other.mPositionX, other.mPositionY,
-                other.mScaleX, other.mScaleY,
-                other.mRotation, other.mCornerRadius,
-                other.mWindowCrop);
+                other.mFloat9, other.mRotation, other.mCornerRadius, other.mWindowCrop);
     }
 
-    public Rect getWindowCrop() {
-        return new Rect(mWindowCrop);
+    /** @return {@link Matrix} from {@link #mFloat9} */
+    public Matrix getMatrix() {
+        final Matrix matrix = new Matrix();
+        matrix.setValues(mFloat9);
+        return matrix;
     }
 
     @Override
@@ -88,8 +89,7 @@
         PictureInPictureSurfaceTransaction that = (PictureInPictureSurfaceTransaction) o;
         return Objects.equals(mPositionX, that.mPositionX)
                 && Objects.equals(mPositionY, that.mPositionY)
-                && Objects.equals(mScaleX, that.mScaleX)
-                && Objects.equals(mScaleY, that.mScaleY)
+                && Arrays.equals(mFloat9, that.mFloat9)
                 && Objects.equals(mRotation, that.mRotation)
                 && Objects.equals(mCornerRadius, that.mCornerRadius)
                 && Objects.equals(mWindowCrop, that.mWindowCrop);
@@ -97,7 +97,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mPositionX, mPositionY, mScaleX, mScaleY,
+        return Objects.hash(mPositionX, mPositionY, Arrays.hashCode(mFloat9),
                 mRotation, mCornerRadius, mWindowCrop);
     }
 
@@ -110,8 +110,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeFloat(mPositionX);
         out.writeFloat(mPositionY);
-        out.writeFloat(mScaleX);
-        out.writeFloat(mScaleY);
+        out.writeFloatArray(mFloat9);
         out.writeFloat(mRotation);
         out.writeFloat(mCornerRadius);
         out.writeTypedObject(mWindowCrop, 0 /* flags */);
@@ -119,11 +118,11 @@
 
     @Override
     public String toString() {
+        final Matrix matrix = getMatrix();
         return "PictureInPictureSurfaceTransaction("
                 + " posX=" + mPositionX
                 + " posY=" + mPositionY
-                + " scaleX=" + mScaleX
-                + " scaleY=" + mScaleY
+                + " matrix=" + matrix.toShortString()
                 + " rotation=" + mRotation
                 + " cornerRadius=" + mCornerRadius
                 + " crop=" + mWindowCrop
@@ -134,15 +133,11 @@
     public static void apply(@NonNull PictureInPictureSurfaceTransaction surfaceTransaction,
             @NonNull SurfaceControl surfaceControl,
             @NonNull SurfaceControl.Transaction tx) {
-        final Matrix matrix = new Matrix();
-        matrix.setScale(surfaceTransaction.mScaleX, surfaceTransaction.mScaleY);
-        if (surfaceTransaction.mRotation != 0) {
-            matrix.postRotate(surfaceTransaction.mRotation);
-        }
+        final Matrix matrix = surfaceTransaction.getMatrix();
         tx.setMatrix(surfaceControl, matrix, new float[9])
                 .setPosition(surfaceControl,
                         surfaceTransaction.mPositionX, surfaceTransaction.mPositionY)
-                .setWindowCrop(surfaceControl, surfaceTransaction.getWindowCrop())
+                .setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop)
                 .setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius);
     }
 
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 83def0c..49a3e29 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.media.AudioAttributes;
 import android.media.Ringtone;
@@ -597,7 +598,11 @@
         }
 
         public AlertDialog.Builder getAlertDialogBuilder(Context context) {
-            return new AlertDialog.Builder(context);
+            final boolean inNightMode = (context.getResources().getConfiguration().uiMode
+                    & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
+            final int themeId = inNightMode ? R.style.Theme_DeviceDefault_Dialog_Alert :
+                    R.style.Theme_DeviceDefault_Light_Dialog_Alert;
+            return new AlertDialog.Builder(context, themeId);
         }
 
         public Toast makeToastFromText(Context context, CharSequence charSequence, int duration) {
diff --git a/core/java/com/android/internal/os/BatteryChargeCalculator.java b/core/java/com/android/internal/os/BatteryChargeCalculator.java
index 16f92ef..0690d1f 100644
--- a/core/java/com/android/internal/os/BatteryChargeCalculator.java
+++ b/core/java/com/android/internal/os/BatteryChargeCalculator.java
@@ -42,6 +42,8 @@
                 batteryCapacityMah = batteryStats.getEstimatedBatteryCapacity();
             }
         }
+        builder.setBatteryCapacity(batteryCapacityMah);
+
         final double dischargedPowerLowerBoundMah =
                 batteryStats.getLowDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
         final double dischargedPowerUpperBoundMah =
diff --git a/core/java/com/android/internal/os/PowerCalculator.java b/core/java/com/android/internal/os/PowerCalculator.java
index d139b4f..4979ecb 100644
--- a/core/java/com/android/internal/os/PowerCalculator.java
+++ b/core/java/com/android/internal/os/PowerCalculator.java
@@ -24,6 +24,7 @@
 import android.os.UserHandle;
 import android.util.SparseArray;
 
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Locale;
 
@@ -157,6 +158,12 @@
         }
     }
 
+    /**
+     * Prints formatted amount of power in milli-amp-hours.
+     */
+    public static void printPowerMah(PrintWriter pw, double powerMah) {
+        pw.print(formatCharge(powerMah));
+    }
 
     /**
      * Converts charge in mAh to string.
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index f19a123..5ba1928 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -271,4 +271,9 @@
      * @param enable {@code true} if enable, otherwise set to {@code false}.
      */
     void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable);
+
+    /**
+     * Triggers a GC in the system and status bar.
+     */
+    void runGcForTest();
 }
diff --git a/core/java/com/android/internal/util/GcUtils.java b/core/java/com/android/internal/util/GcUtils.java
new file mode 100644
index 0000000..e37ba3c
--- /dev/null
+++ b/core/java/com/android/internal/util/GcUtils.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.internal.util;
+
+import android.util.Slog;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A helper class to handle gc'ing a process, mainly used for testing.
+ *
+ * @hide
+ */
+public final class GcUtils {
+    private static final String TAG = GcUtils.class.getSimpleName();
+
+    /**
+     * Runs a GC and attempts to wait for finalization.
+     */
+    public static void runGcAndFinalizersSync() {
+        Runtime.getRuntime().gc();
+        Runtime.getRuntime().runFinalization();
+
+        final CountDownLatch fence = new CountDownLatch(1);
+        createFinalizationObserver(fence);
+        try {
+            do {
+                Runtime.getRuntime().gc();
+                Runtime.getRuntime().runFinalization();
+            } while (!fence.await(100, TimeUnit.MILLISECONDS));
+        } catch (InterruptedException ex) {
+            throw new RuntimeException(ex);
+        }
+        Slog.v(TAG, "Running gc and finalizers");
+    }
+
+    /**
+     * Create the observer in the scope of a method to minimize the chance that
+     * it remains live in a DEX/machine register at the point of the fence guard.
+     * This must be kept to avoid R8 inlining it.
+     */
+    private static void createFinalizationObserver(CountDownLatch fence) {
+        new Object() {
+            @Override
+            protected void finalize() throws Throwable {
+                try {
+                    fence.countDown();
+                } finally {
+                    super.finalize();
+                }
+            }
+        };
+    }
+
+    // Uninstantiable
+    private GcUtils() {}
+}
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 88e4e35..d2d8220 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -158,7 +158,7 @@
      *     be converted to a string using {@link String#valueOf(Object)}
      * @return the non-null reference that was validated
      * @throws NullPointerException if {@code reference} is null
-     * @deprecated - use {@link java.util.Objects.requireNonNull} instead.
+     * @deprecated - use {@link java.util.Objects#requireNonNull} instead.
      */
     @Deprecated
     @UnsupportedAppUsage
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 5eb1e00..56814c7 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2382,10 +2382,19 @@
     return (jint)nativeToJavaStatus(status);
 }
 
-static jint android_media_AudioSystem_get_FCC_8(JNIEnv *env, jobject thiz) {
+static jint android_media_AudioSystem_getMaxChannelCount(JNIEnv *env, jobject thiz) {
     return FCC_8;
 }
 
+static jint android_media_AudioSystem_getMaxSampleRate(JNIEnv *env, jobject thiz) {
+    // see frameworks/av/services/audiopolicy/common/include/policy.h
+    return 192000; // SAMPLE_RATE_HZ_MAX (for API)
+}
+
+static jint android_media_AudioSystem_getMinSampleRate(JNIEnv *env, jobject thiz) {
+    return 4000; // SAMPLE_RATE_HZ_MIN  (for API)
+}
+
 static jint
 android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
 {
@@ -2810,14 +2819,18 @@
         (void *)android_media_AudioSystem_eventHandlerFinalize},
 };
 
-static const JNINativeMethod gGetFCC8Methods[] = {
-    {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
+static const JNINativeMethod gFrameworkCapabilities[] = {
+        {"native_getMaxChannelCount", "()I", (void *)android_media_AudioSystem_getMaxChannelCount},
+        {"native_getMaxSampleRate", "()I", (void *)android_media_AudioSystem_getMaxSampleRate},
+        {"native_getMinSampleRate", "()I", (void *)android_media_AudioSystem_getMinSampleRate},
 };
 
 int register_android_media_AudioSystem(JNIEnv *env)
 {
     // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
-    RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
+    // as the calls are performed in the static initializer of AudioSystem.
+    RegisterMethodsOrDie(env, kClassPathName, gFrameworkCapabilities,
+                         NELEM(gFrameworkCapabilities));
 
     jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
     gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4e7dd91..ffb8d1d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -696,6 +696,8 @@
     <protected-broadcast android:name="android.scheduling.action.REBOOT_READY" />
     <protected-broadcast android:name="android.app.action.DEVICE_POLICY_CONSTANTS_CHANGED" />
 
+    <protected-broadcast android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index da2ea3e..73adeaa 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Teks na knipbord gekopieër."</string>
     <string name="copied" msgid="4675902854553014676">"Gekopieer"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het uit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> geplak"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> van jou knipbord af geplak"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het teks geplak wat jy gekopieer het"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het \'n prent geplak wat jy gekopieer het"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het inhoud geplak wat jy gekopieer het"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Berei tans <xliff:g id="APPNAME">%1$s</xliff:g> voor."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Begin programme."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Voltooi herlaai."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Skakel skerm af?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Jy het die aan/af-skakelaar gedruk terwyl jy jou vingerafdruk gestel het.\n\nDit skakel gewoonlik jou skerm af."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Skakel af"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Kanselleer"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> loop"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Tik om na die speletjie terug te keer"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Kies speletjie"</string>
@@ -1875,10 +1870,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Opgedateer deur jou administrateur"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte, sekere kenmerke en sommige netwerkverbindings af.\n\n"<annotation id="url">"Kom meer te wete"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte, sekere kenmerke en sommige netwerkverbindings af"</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Databespaarder verhoed sommige programme om data in die agtergrond te stuur of te aanvaar om datagebruik te help verminder. \'n Program wat jy tans gebruik kan by data ingaan, maar sal dit dalk minder gereeld doen. Dit kan byvoorbeeld beteken dat prente nie wys voordat jy op hulle tik nie."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Skakel Databespaarder aan?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Skakel aan"</string>
@@ -1981,10 +1974,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> is nie nou onmiddellik beskikbaar nie. Dit word bestuur deur <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Kom meer te wete"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Hervat program"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Skakel werkprogramme aan?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Kry toegang tot jou werkprogramme en -kennisgewings"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Skakel aan"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c1a8b1e..f8ff934 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"ፅሁፍ ወደ ቅንጥብ ሰሌዳ ተገልብጧል።"</string>
     <string name="copied" msgid="4675902854553014676">"ተቀድቷል"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ተለጥፏል"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከእርስዎ ቅንጥብ ሰሌዳ ተለጥፏል"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> እርስዎ የቀዱትን ጽሑፍ ለጥፏል"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> እርስዎ የቀዱትን ምስል ለጥፏል"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> እርስዎ የቀዱትን ይዘት ለጥፏል"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>ን ማዘጋጀት።"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"አጨራረስ ማስነሻ፡፡"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"ማያ ገጽ ይጥፋ?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"የጣት አሻራዎን ሲያዋቅሩ የኃይል አዝራሩን ተጫንተውታል። \n\n ይህ አብዛኛው ጊዜ ማያ ገጽዎን ያጠፈዋል።"</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"አጥፋ"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"ይቅር"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> አሂድ"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"ወደ ጨዋታ ለመመለስ መታ ያድርጉ"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"ጨዋታ ይምረጡ"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"የቀለም ማስተካከያ"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"የአንድ እጅ ሁነታ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ተጨማሪ ደብዛዛ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index fa5f8e4..8101c28 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ৰং শুধৰণি"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এখন হাতেৰে ব্যৱহাৰ কৰাৰ ম’ড"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"এক্সট্ৰা ডিম"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index b682a16..2681451 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1025,8 +1025,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekst je kopiran u privremenu memoriju."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano je"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila podatke iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Sadržaj aplikacije <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepljen u privr. memoriju"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila tekst koji ste kopirali"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sliku koju ste kopirali"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sadržaj koji ste kopirali"</string>
@@ -1280,14 +1279,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Priprema se <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završavanje pokretanja."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Želite da isključite ekran?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Pritisli ste dugme za uključivanje tokom podešavanja otiska prsta.\n\nTako se najčešće isključuje ekran."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Isključi"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Otkaži"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Dodirnite da biste se vratili u igru"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Odaberite igru"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 2999945c3..9dedb88 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"ক্লিপবোর্ডে পাঠ্য অনুলিপি করা হয়েছে৷"</string>
     <string name="copied" msgid="4675902854553014676">"কপি করা হয়েছে"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> থেকে কপি করা ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"আপনার ক্লিপবোর্ড থেকে <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পেস্ট করা হয়েছে"</string>
     <string name="pasted_text" msgid="4298871641549173733">"আপনার কপি করা টেক্সট <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
     <string name="pasted_image" msgid="4729097394781491022">"আপনার কপি করা ছবি <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
     <string name="pasted_content" msgid="646276353060777131">"আপনার কপি করা কন্টেন্ট <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> প্রস্তুত করা হচ্ছে৷"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"স্ক্রিন বন্ধ করবেন?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"আপনার আঙ্গুলের ছাপ সেট আপ করার সময়, পাওয়ার বোতাম প্রেস করেছিলেন।\n\nএর ফলে সাধারণত আপনার স্ক্রিন বন্ধ হয়ে যায়।"</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"বন্ধ করুন"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"বাতিল করুন"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> চলছে"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"গেমে ফিরে আসতে ট্যাপ করুন"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"গেম বেছে নিন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 96cec5a..c918d8c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1025,8 +1025,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međumemoriju."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepljena iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila sadržaj iz međumemorije"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila kopirani tekst"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila kopiranu sliku"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila kopirani sadržaj"</string>
@@ -1280,14 +1279,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripremanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Pokretanje pri kraju."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Isključiti ekran?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Prilikom postavljanja otiska prsta, pritisnuli ste dugme za uključivanje.\n\nTime se obično isključuje ekran."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Isključi"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Otkaži"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Pokrenuta je aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Dodirnite za povratak u igru"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Odaberite igru"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 77b7911..402402f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Text copiat al Porta-retalls."</string>
     <string name="copied" msgid="4675902854553014676">"S\'ha copiat"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat dades de: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat contingut del porta-retalls"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat text que has copiat"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat una imatge que has copiat"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat contingut que has copiat"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"S\'està preparant <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"S\'estan iniciant les aplicacions."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"S\'està finalitzant l\'actualització."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vols apagar la pantalla?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Mentre configuraves la teva empremta digital has premut el botó d\'engegada.\n\nAixò normalment apaga la pantalla."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desactiva"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancel·la"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toca per tornar al joc"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Tria el joc"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7e40710..17ddb0e 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1028,8 +1028,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Text byl zkopírován do schránky."</string>
     <string name="copied" msgid="4675902854553014676">"Zkopírováno"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila data z aplikace <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila obsah ze schránky"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila zkopírovaný text"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila zkopírovaný obrázek"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila zkopírovaný obsah"</string>
@@ -1300,14 +1299,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Příprava aplikace <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Spouštění aplikací."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Dokončování inicializace."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vypnout obrazovku?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Při nastavování otisku prstu jste stiskli vypínač.\n\nTen obvykle vypne obrazovku."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Vypnout"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Zrušit"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Běží aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Klepnutím se vrátíte do hry"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Vyberte hru"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 697071c..d4aced53 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Teksten er kopieret til udklipsholderen."</string>
     <string name="copied" msgid="4675902854553014676">"Kopieret"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra din udklipsholder"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte tekst, som du har kopieret"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte et billede, som du har kopieret"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold, som du har kopieret"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Åbner dine apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Gennemfører start."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vil du slukke skærmen?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Ved konfigurationen af dit fingeraftryk trykkede du på afbryderknappen.\n\nDet medfører normalt, at din skærm slukkes."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Sluk"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Annuller"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> er i gang"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Tryk for at vende tilbage til spillet"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Vælg et spil"</string>
@@ -1875,10 +1870,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Opdateret af din administrator"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Batterisparefunktionen aktiverer Mørkt tema og begrænser eller deaktiverer aktivitet i baggrunden og visse visuelle effekter, funktioner og netværksforbindelser.\n\n"<annotation id="url">"Få flere oplysninger"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Batterisparefunktionen aktiverer Mørkt tema og begrænser eller deaktiverer aktivitet i baggrunden og visse visuelle effekter, funktioner og netværksforbindelser."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Datasparefunktionen forhindrer nogle apps i at sende eller modtage data i baggrunden for at reducere dataforbruget. En app, der er i brug, kan få adgang til data, men gør det måske ikke så ofte. Dette kan f.eks. betyde, at billeder ikke vises, før du trykker på dem."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du aktivere Datasparefunktion?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivér"</string>
@@ -1981,10 +1974,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> er ikke tilgængelig lige nu. Dette administreres af <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Få flere oplysninger"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Afslut pause for app"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Vil du aktivere arbejdsapps?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Få adgang til dine arbejdsapps og notifikationer"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Slå til"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8575a1d..bd01896 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Farbkorrektur"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhandmodus"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradunkel"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index d807093..1f11664 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Το κείμενο αντιγράφηκε στο πρόχειρο."</string>
     <string name="copied" msgid="4675902854553014676">"Αντιγράφηκε"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από την εφαρμογή <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε δεδομένα από το πρόχειρο"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε το κείμενο που αντιγράψατε"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε την εικόνα που αντιγράψατε"</string>
     <string name="pasted_content" msgid="646276353060777131">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε περιεχόμενο που αντιγράψατε"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Προετοιμασία <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Έναρξη εφαρμογών."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ολοκλήρωση εκκίνησης."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Απενεργοποίηση οθόνης;"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Κατά τη ρύθμιση του δακτυλικού σας αποτυπώματος, πατήσατε το κουμπί λειτουργίας.\n\nΑυτό απενεργοποιεί συνήθως την οθόνη."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Απενεργοποίηση"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Ακύρωση"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Πατήστε για να επιστρέψετε στο παιχνίδι"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Επιλέξτε παιχνίδι"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Διόρθωση χρωμάτων"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Λειτουργία ενός χεριού"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Επιπλέον μείωση φωτεινότητας"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 146df87..624a678 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado en el portapapeles."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó información del portapapeles"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> accedió a texto del portapapeles"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> accedió a una imagen del portapapeles"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> accedió al contenido del portapapeles"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando el inicio"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"¿Quieres apagar la pantalla?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Al configurar tu huella dactilar, presionaste el botón de encendido.\n\nPor lo general, esta acción apaga la pantalla."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Apagar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Presiona para volver al juego"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Elige un juego"</string>
@@ -1874,10 +1869,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Tu administrador actualizó este paquete"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Tu administrador borró este paquete"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"El Ahorro de batería activa el Tema oscuro y desactiva o restringe la actividad en segundo plano, algunos efectos visuales, algunas conexiones de red y otras funciones determinadas.\n\n"<annotation id="url">"Más información"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"El Ahorro de batería activa el Tema oscuro y desactiva o restringe la actividad en segundo plano, algunos efectos visuales, algunas conexiones de red y otras funciones determinadas."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Para reducir el uso de datos, el modo Ahorro de datos evita que algunas apps envíen y reciban datos en segundo plano. La app que estés usando podrá acceder a los datos, pero con menor frecuencia. De esta forma, por ejemplo, las imágenes no se mostrarán hasta que las presiones."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Deseas activar Ahorro de datos?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
@@ -1980,10 +1973,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> no está disponible en este momento. Esta opción se administra en <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Más información"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Reanudar app"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"¿Activar apps de trabajo?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Obtén acceso a tus apps de trabajo y notificaciones"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index abcb432..00a7522 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado al portapapeles."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Se ha pegado <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> desde el portapapeles"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado texto que has copiado"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado una imagen que has copiado"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido que has copiado"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando inicio..."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"¿Apagar pantalla?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Has pulsado el botón de encendido mientras configurabas tu huella digital.\n\nAl hacer esto, se suele apagar la pantalla."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desactivar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toca para volver al juego"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Elegir juego"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 679b491..428832d 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Testua arbelean kopiatu da."</string>
     <string name="copied" msgid="4675902854553014676">"Kopiatu da"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> aplikaziotik itsatsi da <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak arbeletik itsatsi du"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak kopiatu duzun testua itsatsi du"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak kopiatu duzun irudia itsatsi du"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak kopiatu duzun edukia itsatsi du"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> prestatzen."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Bertsio-berritzea amaitzen."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Pantaila itzali nahi duzu?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Hatz-marka konfiguratzean, etengailua sakatu duzu.\n\nNormalean, horren ondorioz pantaila itzali egiten da."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desaktibatu"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Utzi"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> abian da"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Sakatu jokora itzultzeko"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Aukeratu joko bat"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Esku bakarreko modua"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Are ilunago"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 68c5b0d..b66ad5a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"متن در بریده‌دان کپی شد."</string>
     <string name="copied" msgid="4675902854553014676">"کپی شد"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> جای‌گذاری کرد"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از بریده‌دان جای‌گذاری کرد"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نوشتاری را که کپی کردید جای‌گذاری کرد"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> تصویری را که کپی کردید جای‌گذاری کرد"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوایی را که کپی کردید جای‌گذاری کرد"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"درحال آغاز کردن برنامه‌ها."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"درحال اتمام راه‌اندازی."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"صفحه‌نمایش خاموش شود؟"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"هنگام راه‌اندازی اثر انگشتتان، دکمه روشن/ خاموش را فشار دادید.\n\nاین کار معمولاً صفحه‌نمایش را خاموش می‌کند."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"خاموش شود"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"لغو شود"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشت به بازی، ضربه بزنید"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"انتخاب بازی"</string>
@@ -1875,10 +1870,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"توسط سرپرست سیستم به‌روزرسانی شد"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"توسط سرپرست سیستم حذف شد"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"تأیید"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"«بهینه‌سازی باتری» «طرح زمینه تیره» را روشن می‌کند و فعالیت پس‌زمینه، برخی از جلوه‌های بصری، ویژگی‌هایی خاص، و برخی از اتصال‌های شبکه را محدود یا خاموش می‌کند.\n\n"<annotation id="url">"بیشتر بدانید"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"«بهینه‌سازی باتری» «طرح زمینه تیره» را روشن می‌کند و فعالیت پس‌زمینه، برخی از جلوه‌های بصری، ویژگی‌هایی خاص، و برخی از اتصال‌های شبکه را محدود یا خاموش می‌کند."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"برای کمک به کاهش مصرف داده، «صرفه‌جویی داده» از ارسال و دریافت داده در پس‌زمینه در بعضی برنامه‌ها جلوگیری می‌کند. برنامه‌ای که درحال‌حاضر استفاده می‌کنید می‌تواند به داده‌ها دسترسی داشته باشد اما دفعات دسترسی آن محدود است. این می‌تواند به این معنی باشد که، برای مثال، تصاویر تازمانی‌که روی آن‌ها ضربه نزنید نشان داده نمی‌شوند."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"«صرفه‌جویی داده» روشن شود؟"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"روشن کردن"</string>
@@ -1981,10 +1974,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> درحال‌حاضر در دسترس نیست. <xliff:g id="APP_NAME_1">%2$s</xliff:g> آن را مدیریت می‌کند."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"بیشتر بدانید"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"لغو توقف موقت برنامه"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"برنامه‌های کاری روشن شود؟"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"دسترسی به اعلان‌ها و برنامه‌های کاری"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"روشن کردن"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"برنامه در دسترس نیست"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال‌حاضر در دسترس نیست."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ee6e934..28990b4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Le texte a été copié dans le presse-papier."</string>
     <string name="copied" msgid="4675902854553014676">"Copie effectuée"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé depuis <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a copié des données depuis le presse-papiers"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du texte que vous avez copié"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé une image que vous avez copiée"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé le contenu que vous avez copié"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Éteindre l\'écran ?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Vous avez appuyé sur le bouton Marche/Arrêt pendant la configuration de votre empreinte digitale.\n\nCela éteint généralement l\'écran."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Éteindre"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Annuler"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Appuyez pour revenir au jeu"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Choisir un jeu"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode une main"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Encore moins lumineux"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 4bb6aa6..e2bd3cb 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"O texto copiouse no portapapeis."</string>
     <string name="copied" msgid="4675902854553014676">"Copiuse"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido procedente de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido do portapapeis"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou texto que copiaches"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou unha imaxe que copiaches"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido que copiaches"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicacións."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Está finalizando o arranque"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Queres apagar a pantalla?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Premiches o botón de acendido mentres configurabas a impresión dixital.\n\nAo realizar esta acción, normalmente apágase a pantalla."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Apagar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> está en execución"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toca para volver ao xogo"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Escolle un xogo"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 20da0ac..b4594e1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"लेख को क्‍लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="copied" msgid="4675902854553014676">"कॉपी किया गया"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> से कॉपी किए गए डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने क्लिपबोर्ड में मौजूद डेटा कॉपी करके चिपकाया"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपका कॉपी किया हुआ टेक्स्ट चिपका दिया है"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपकी कॉपी की हुई इमेज चिपका दी है"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपका कॉपी किया हुआ कॉन्टेंट चिपका दिया है"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> तैयार हो रहा है."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ऐप्स  प्रारंभ होने वाले हैं"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बूट खत्म हो रहा है."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"स्क्रीन बंद करें?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"अपना फ़िंगरप्रिंट सेट अप करते समय, आपने पावर बटन दबाया.\n\nआम तौर पर, इससे स्क्रीन बंद हो जाती है."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"बंद करें"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"अभी नहीं"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> चल रही है"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"गेम पर वापस जाने के लिए टैप करें"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"गेम चुनें"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"रंग में सुधार करने की सुविधा"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"वन-हैंडेड मोड"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index be2307b..8759f7a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1025,8 +1025,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međuspremnik."</string>
     <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"U aplikaciji <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepljen je sadržaj aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Zalijepljen je sadržaj aplikacije <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepila je tekst koji ste kopirali"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepila je sliku koju ste kopirali"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepila je ono što ste kopirali"</string>
@@ -1280,14 +1279,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripremanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završetak inicijalizacije."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Isključiti zaslon?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Prilikom postavljanja otiska prsta pritisnuli ste tipku za uključivanje/isključivanje.\n\nTom se radnjom obično isključuje zaslon."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Isključi"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Odustani"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Izvodi se <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Dodirnite za povratak na igru"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Odabir igre"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c57d555..dd4afa53 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"A szöveg bemásolva a vágólapra."</string>
     <string name="copied" msgid="4675902854553014676">"Átmásolva"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tartalmat másolt vágólapra a(z) <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> appból"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztett a vágólapról"</string>
     <string name="pasted_text" msgid="4298871641549173733">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztette a másolt szöveget"</string>
     <string name="pasted_image" msgid="4729097394781491022">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztette a másolt képet"</string>
     <string name="pasted_content" msgid="646276353060777131">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztette a másolt tartalmat"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> előkészítése."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Kezdő alkalmazások."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Rendszerindítás befejezése."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Kikapcsolja a képernyőt?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Ujjlenyomata beállítása közben megnyomta a bekapcsológombot.\n\nEz általában kikapcsolja a képernyőt."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Kikapcsolás"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Mégse"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Koppintson ide a játékhoz való visszatéréshez"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Játék kiválasztása"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 0c653a1..990f94d 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode satu tangan"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra redup"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index f4055ce..ba889b6 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texti afritaður á klippiborð."</string>
     <string name="copied" msgid="4675902854553014676">"Afritað"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límt úr <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi af klippiborðinu"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi texta sem þú afritaðir"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi mynd sem þú afritaðir"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi efni sem þú afritaðir"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Undirbýr <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ræsir forrit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Lýkur ræsingu."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Slökkva á skjá?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Þú ýttir á aflrofann þegar þú varst að skrá fingrafarið þitt.\n\nYfirleitt slekkur það á skjánum."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Slökkva"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Hætta við"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> er í gangi"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Ýttu til að fara aftur í leik"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Velja leik"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 35980c3..411c4e1 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Testo copiato negli appunti."</string>
     <string name="copied" msgid="4675902854553014676">"Copia eseguita"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Dati dell\'app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> incollati dall\'app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"L\'app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato dati dagli appunti"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato il testo che hai copiato"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato un\'immagine che hai copiato"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato i contenuti che hai copiato"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> in preparazione."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Avvio app."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Conclusione dell\'avvio."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vuoi disattivare lo schermo?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Durante la configurazione della tua impronta hai premuto il tasto di accensione.\n\nGeneralmente questa azione comporta la disattivazione dello schermo."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Disattiva"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Annulla"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> in esecuzione"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Tocca per tornare al gioco"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Scegli gioco"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5a7eba3..7238cde 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"テキストをクリップボードにコピーしました。"</string>
     <string name="copied" msgid="4675902854553014676">"コピーしました"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> から <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> に貼り付けました"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> にクリップボードから貼り付けました"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> がクリップボード内のテキストを貼り付けました"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> がクリップボード内の画像を貼り付けました"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> がクリップボード内のコンテンツを貼り付けました"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>をペア設定しています。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"アプリを起動しています。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ブートを終了しています。"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"画面を OFF にしますか?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"指紋の設定中に電源ボタンが押されました。\n\n通常、この操作により画面が OFF になります。"</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"OFF にする"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"キャンセル"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g>を実行中"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"タップするとゲームに戻ります"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"ゲームの選択"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 8a9547b..a2b337d 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ფერთა კორექცია"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ცალი ხელის რეჟიმი"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"დამატებითი დაბინდვა"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index ea6d6de..31f2b50 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"បាន​ចម្លង​អត្ថបទ​ទៅ​ក្ដារ​តម្បៀត​ខ្ទាស់។"</string>
     <string name="copied" msgid="4675902854553014676">"បា​នចម្លង"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពី <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​ពីឃ្លីបបត​របស់អ្នក"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​អត្ថបទ​ដែលអ្នក​បានចម្លង"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​រូបភាព​ដែលអ្នក​បានចម្លង"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូល​ខ្លឹមសារ​ដែលអ្នក​បានចម្លង"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"កំពុងរៀបចំ <xliff:g id="APPNAME">%1$s</xliff:g>។"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ចាប់ផ្ដើម​កម្មវិធី។"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"បញ្ចប់​ការ​ចាប់ផ្ដើម។"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"បិទ​អេក្រង់ឬ?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"នៅពេលរៀបចំ​ស្នាមម្រាមដៃ​របស់អ្នក អ្នកបានចុច​ប៊ូតុងថាមពល។\n\nជាធម្មតា ការធ្វើបែបនេះ​បិទអេក្រង់​របស់អ្នក។"</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"បិទ"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"បោះបង់"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"ចុច​ដើម្បី​ត្រឡប់​ទៅ​ហ្គេមវិញ"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"ជ្រើសរើស​ហ្គេម"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 126e1f4..f3d0d58 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1875,10 +1875,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಪ್‌ಡೇಟ್ ಮಾಡಲ್ಪಟ್ಟಿದೆ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಳಿಸಿದ್ದಾರೆ"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ಸರಿ"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್‌ಗಳು, ಕೆಲವು ವೈಶಿಷ್ಟ್ಯಗಳು ಮತ್ತು ಇತರ ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕಗಳನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಆಫ್ ಮಾಡುತ್ತದೆ.\n\n"<annotation id="url">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್‌ಗಳು, ಕೆಲವು ವೈಶಿಷ್ಟ್ಯಗಳು ಮತ್ತು ಇತರ ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕಗಳನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಆಫ್ ಮಾಡುತ್ತದೆ."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"ಡೇಟಾ ಬಳಕೆ ಕಡಿಮೆ ಮಾಡುವ ನಿಟ್ಟಿನಲ್ಲಿ, ಡೇಟಾ ಸೇವರ್ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಡೇಟಾ ಕಳುಹಿಸುವುದನ್ನು ಅಥವಾ ಸ್ವೀಕರಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. ನೀವು ಪ್ರಸ್ತುತ ಬಳಸುತ್ತಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಆದರೆ ಪದೇ ಪದೇ ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಇದರರ್ಥ, ಉದಾಹರಣೆಗೆ, ನೀವು ಅವುಗಳನ್ನು ಟ್ಯಾಪ್ ಮಾಡುವವರೆಗೆ ಆ ಚಿತ್ರಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುವುದಿಲ್ಲ."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"ಡೇಟಾ ಸೇವರ್ ಆನ್ ಮಾಡಬೇಕೇ?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"ಆನ್‌ ಮಾಡಿ"</string>
@@ -1981,10 +1979,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ. ಇದನ್ನು <xliff:g id="APP_NAME_1">%2$s</xliff:g> ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"ಆ್ಯಪ್ ವಿರಾಮ ನಿಲ್ಲಿಸಿ"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"ಕೆಲಸ ಆ್ಯಪ್‌ಗಳನ್ನು ಆನ್ ಮಾಡಬೇಕೆ?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಪಡೆಯಿರಿ"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ಆನ್‌ ಮಾಡಿ"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"ಆ್ಯಪ್ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಇದೀಗ ಲಭ್ಯವಿಲ್ಲ."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index b0782ab..667057f3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"ສຳເນົາຂໍ້ຄວາມໃສ່ຄລິບບອດແລ້ວ."</string>
     <string name="copied" msgid="4675902854553014676">"ສຳເນົາແລ້ວ"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ແລ້ວ"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຈາກຄລິບບອດຂອງທ່ານແລ້ວ"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຂໍ້ຄວາມທີ່ທ່ານສຳເນົາແລ້ວ"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຮູບທີ່ທ່ານສຳເນົາແລ້ວ"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງເນື້ອຫາທີ່ທ່ານສຳເນົາແລ້ວ"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"ກຳ​ລັງ​ກຽມ <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ກຳລັງເປີດແອັບຯ."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"ປິດໜ້າຈໍໄວ້ບໍ?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"ໃນລະຫວ່າງການຕັ້ງຄ່າລາຍນິ້ວມືຂອງທ່ານ, ທ່ານກົດປຸ່ມເປີດປິດ.\n\nໂດຍປົກກະຕິນີ້ຈະເປັນການປິດໜ້າຈໍຂອງທ່ານ."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"ປິດໄວ້"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"ຍົກເລີກ"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກ"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Tap to return to game"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Choose game"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ການແກ້ໄຂຄ່າສີ"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ໂໝດມືດຽວ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ຫຼຸດແສງເປັນພິເສດ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4497d9a..75facc1 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1028,8 +1028,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekstas nukopijuotas į iškarpinę."</string>
     <string name="copied" msgid="4675902854553014676">"Nukopijuota"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš „<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>“"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš iškarpinės"</string>
     <string name="pasted_text" msgid="4298871641549173733">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijavo jūsų nukopijuotą tekstą"</string>
     <string name="pasted_image" msgid="4729097394781491022">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijavo jūsų nukopijuotą vaizdą"</string>
     <string name="pasted_content" msgid="646276353060777131">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijavo jūsų nukopijuotą turinį"</string>
@@ -1300,14 +1299,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Ruošiama „<xliff:g id="APPNAME">%1$s</xliff:g>“."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Paleidžiamos programos."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Užbaigiamas paleidimas."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Išjungti ekraną?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Nustatydami kontrolinį kodą paspaudėte maitinimo mygtuką.\n\nĮprastai juo išjungiamas ekranas."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Išjungti"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Atšaukti"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Vykdoma „<xliff:g id="APP">%1$s</xliff:g>“"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Palieskite, kad grįžtumėte į žaidimą"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Pasirinkite žaidimą"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 618f8d6..876f522 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Текстот е копиран на таблата со исечоци."</string>
     <string name="copied" msgid="4675902854553014676">"Копирано"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од вашата привремена меморија"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> го залепи текстот што го копиравте"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ја залепи сликата што ја копиравте"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ги залепи содржините што ги копиравте"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Се подготвува <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Се стартуваат апликациите."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Подигањето завршува."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Да се исклучи екранот?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Додека го поставувавте вашиот отпечаток, го притиснавте копчето за вклучување.\n\nОва обично го исклучува екранот."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Исклучи"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Откажи"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> работи"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Допрете за да се вратите во играта"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Избор на игра"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5d411bd..ab08384 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -42,10 +42,10 @@
     <string name="serviceErased" msgid="997354043770513494">"Амжилттай арилгалаа."</string>
     <string name="passwordIncorrect" msgid="917087532676155877">"Буруу нууц үг"</string>
     <string name="mmiComplete" msgid="6341884570892520140">"MMI дууссан."</string>
-    <string name="badPin" msgid="888372071306274355">"Таны бичсэн хуучин PIN буруу байна."</string>
+    <string name="badPin" msgid="888372071306274355">"Таны бичсэн хуучин ПИН буруу байна."</string>
     <string name="badPuk" msgid="4232069163733147376">"Таны бичсэн PUК буруу байна."</string>
-    <string name="mismatchPin" msgid="2929611853228707473">"Таны оруулсан PIN таарахгүй байна."</string>
-    <string name="invalidPin" msgid="7542498253319440408">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="mismatchPin" msgid="2929611853228707473">"Таны оруулсан ПИН таарахгүй байна."</string>
+    <string name="invalidPin" msgid="7542498253319440408">"4-8 тооноос бүтэх ПИН-г бичнэ үү."</string>
     <string name="invalidPuk" msgid="8831151490931907083">"8-с цөөнгүй тооноос бүтэх PUK-г бичнэ үү."</string>
     <string name="needPuk" msgid="7321876090152422918">"SIM картны PUK-түгжигдсэн. Тайлах бол PUK кодыг бичнэ үү."</string>
     <string name="needPuk2" msgid="7032612093451537186">"SIM картыг блокоос гаргах бол PUK2-г бичнэ үү."</string>
@@ -64,7 +64,7 @@
     <string name="CwMmi" msgid="3164609577675404761">"дуудлага хүлээлгэх"</string>
     <string name="BaMmi" msgid="7205614070543372167">"Дуудлага хориглох"</string>
     <string name="PwdMmi" msgid="3360991257288638281">"Нууц үг солих"</string>
-    <string name="PinMmi" msgid="7133542099618330959">"PIN солих"</string>
+    <string name="PinMmi" msgid="7133542099618330959">"ПИН солих"</string>
     <string name="CnipMmi" msgid="4897531155968151160">"Дуудсан дугаар харуулах"</string>
     <string name="CnirMmi" msgid="885292039284503036">"Дуудлага хийгчийн дугаар хязгаарлагдсан"</string>
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Гурван чиглэлт дуудлага"</string>
@@ -866,14 +866,14 @@
     <string name="sipAddressTypeWork" msgid="7873967986701216770">"Ажлын"</string>
     <string name="sipAddressTypeOther" msgid="6317012577345187275">"Бусад"</string>
     <string name="quick_contacts_not_available" msgid="1262709196045052223">"Энэ харилцагчийг харах аппликейшн олдсонгүй."</string>
-    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"PIN кодыг бичнэ үү"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"ПИН кодыг бичнэ үү"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"PUK-г бичээд шинэ ПИН код оруулна уу"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"PUK код"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Шинэ PIN код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Шинэ ПИН код"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Нууц үг шивэх бол товшино уу"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Тайлах нууц үгийг бичнэ үү"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Тайлах PIN-г оруулна уу"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"Буруу PIN код."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Тайлах ПИН-г оруулна уу"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"Буруу ПИН код."</string>
     <string name="keyguard_label_text" msgid="3841953694564168384">"Тайлах бол Цэсийг дараад 0."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Яаралтай тусламжийн дугаар"</string>
     <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Үйлчилгээ байхгүй"</string>
@@ -911,7 +911,7 @@
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"SIM картны түгжээг гаргаж байна…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Та нууц үгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Та PIN кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурсан байна. Та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд Android TV төхөөрөмжийнхөө түгжээг тайлахын тулд Google-д нэвтрэх шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа дахин буруу оролдвол, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Текст хуулагдав."</string>
     <string name="copied" msgid="4675902854553014676">"Хуулсан"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>-с буулгасан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Таны түр санах ойгоос <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-г буулгасан"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> таны хуулсан текстийг буулгасан"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> таны хуулсан зургийг буулгасан"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> таны хуулсан контентыг буулгасан"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Бэлдэж байна <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Апп-г эхлүүлж байна."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Эхлэлийг дуусгаж байна."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Дэлгэцийг унтраах уу?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Та хурууны хээгээ тохируулж байх үед Асаах/унтраах товчийг дарсан байна.\n\nЭнэ нь ихэвчлэн таны дэлгэцийг унтраана."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Унтраах"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Цуцлах"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> ажиллаж байна"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Тоглоом руу буцахын тулд товших"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Тоглоом сонгох"</string>
@@ -1647,24 +1642,24 @@
     <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Хээг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="1342812634464179931">"Буруу хээ"</string>
     <string name="kg_wrong_password" msgid="2384677900494439426">"Нууц үг буруу"</string>
-    <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN буруу"</string>
+    <string name="kg_wrong_pin" msgid="3680925703673166482">"ПИН буруу"</string>
     <plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
       <item quantity="other"><xliff:g id="NUMBER">%d</xliff:g> секундын дараа дахин оролдоно уу.</item>
       <item quantity="one">1 секундын дараа дахин оролдоно уу.</item>
     </plurals>
     <string name="kg_pattern_instructions" msgid="8366024510502517748">"Хээг зурах"</string>
-    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"SIM PIN оруулна уу"</string>
-    <string name="kg_pin_instructions" msgid="7355933174673539021">"PIN оруулна уу"</string>
+    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"SIM ПИН оруулна уу"</string>
+    <string name="kg_pin_instructions" msgid="7355933174673539021">"ПИН оруулна уу"</string>
     <string name="kg_password_instructions" msgid="7179782578809398050">"Нууц үгээ оруулна уу"</string>
     <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM идэвхгүй байна. Үргэлжлүүлэх бол PUK кодыг оруулна уу. Дэлгэрэнгүй мэдээллийг оператороос асууна ууу"</string>
-    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Хүссэн PIN кодоо оруулна уу"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Хүссэн PIN кодоо дахин оруулна уу"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Хүссэн ПИН кодоо оруулна уу"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Хүссэн ПИН кодоо дахин оруулна уу"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"SIM картны түгжээг гаргаж байна…"</string>
-    <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"Буруу PIN код."</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"Буруу ПИН код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"4-8 тооноос бүтэх ПИН-г бичнэ үү."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK код 8 тоотой байх ёстой."</string>
     <string name="kg_invalid_puk" msgid="4809502818518963344">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN кодууд таарахгүй байна"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"ПИН кодууд таарахгүй байна"</string>
     <string name="kg_login_too_many_attempts" msgid="699292728290654121">"Хээ оруулах оролдлого хэт олон"</string>
     <string name="kg_login_instructions" msgid="3619844310339066827">"Түгжээг тайлах бол Google акаунтаараа нэвтэрнэ үү."</string>
     <string name="kg_login_username_hint" msgid="1765453775467133251">"Хэрэглэгчийн нэр (имэйл)"</string>
@@ -1673,8 +1668,8 @@
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"Хэрэглэгчийн нэр эсвэл нууц үг буруу."</string>
     <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Хэрэглэгчийн нэр нууц үгээ мартсан уу?\n"<b>"google.com/accounts/recovery"</b>"-д зочилно уу."</string>
     <string name="kg_login_checking_password" msgid="4676010303243317253">"Бүртгэл шалгаж байна…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Та PIN кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Та PIN кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Та Android TV төхөөрөмжийнхөө түгжээг тайлахаар <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу оролдсон байна. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаагийн амжилтгүй оролдлогын дараагаас таны Android TV төхөөрөмжийг үйлдвэрийн өгөгдмөл төлөвт шинэчлэх бөгөөд хэрэглэгчийн бүх өгөгдөл устах болно."</string>
@@ -1841,14 +1836,14 @@
     <string name="print_service_installed_title" msgid="6134880817336942482">"<xliff:g id="NAME">%s</xliff:g> үйлчилгээ суугдсан"</string>
     <string name="print_service_installed_message" msgid="7005672469916968131">"Идэвхжүүлэх бол товшино уу"</string>
     <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Админы ПИН-г оруулах"</string>
-    <string name="restr_pin_enter_pin" msgid="373139384161304555">"PIN оруулна уу"</string>
+    <string name="restr_pin_enter_pin" msgid="373139384161304555">"ПИН оруулна уу"</string>
     <string name="restr_pin_incorrect" msgid="3861383632940852496">"Буруу"</string>
-    <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Одоогийн PIN"</string>
-    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Шинэ PIN"</string>
-    <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Шинэ PIN-г баталгаажуулах"</string>
-    <string name="restr_pin_create_pin" msgid="917067613896366033">"Өөрчлөлтийг хязгаарлахад зориулан PIN үүсгэх"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN таарахгүй байна. Дахин оролдоно уу."</string>
-    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN хэт богино байна. Хамгийн багадаа 4 цифртэй байх ёстой."</string>
+    <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Одоогийн ПИН"</string>
+    <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Шинэ ПИН"</string>
+    <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Шинэ ПИН-г баталгаажуулах"</string>
+    <string name="restr_pin_create_pin" msgid="917067613896366033">"Өөрчлөлтийг хязгаарлахад зориулан ПИН үүсгэх"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"ПИН таарахгүй байна. Дахин оролдоно уу."</string>
+    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"ПИН хэт богино байна. Хамгийн багадаа 4 цифртэй байх ёстой."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> секундын дараа дахин оролдоно уу</item>
       <item quantity="one">1 секундын дараа дахин оролдоно уу</item>
@@ -1868,7 +1863,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Ажлын <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бэхэлснийг болиулахаасаа өмнө PIN асуух"</string>
+    <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бэхэлснийг болиулахаасаа өмнө ПИН асуух"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"Таны админ суулгасан"</string>
@@ -1997,7 +1992,7 @@
     <string name="profile_encrypted_message" msgid="1128512616293157802">"Ажлын профайлын түгжээг тайлахын тулд дарна уу"</string>
     <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-д холбогдсон"</string>
     <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Файлыг үзэхийн тулд дарна уу"</string>
-    <string name="pin_target" msgid="8036028973110156895">"PIN"</string>
+    <string name="pin_target" msgid="8036028973110156895">"ПИН"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g>-г бэхлэх"</string>
     <string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g>-г тогтоосныг болиулах"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index f937404..d154582 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Pembetulan Warna"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mod sebelah tangan"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Amat malap"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
@@ -1875,10 +1874,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Dikemas kini oleh pentadbir anda"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Penjimat Bateri menghidupkan tema Gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual, ciri tertentu dan sesetengah sambungan rangkaian.\n\n"<annotation id="url">"Ketahui lebih lanjut"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Penjimat Bateri menghidupkan tema Gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual, ciri tertentu dan sesetengah sambungan rangkaian."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Untuk membantu penggunaan data dikurangkan, Penjimat Data menghalang sesetengah apl daripada menghantar atau menerima data di latar. Apl yang sedang digunakan boleh mengakses data tetapi mungkin tidak secara kerap. Perkara ini mungkin bermaksud bahawa imej tidak dipaparkan sehingga anda mengetik pada imej itu, contohnya."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Hidupkan Penjimat Data?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Hidupkan"</string>
@@ -1981,10 +1978,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> tidak tersedia sekarang. Ini diurus oleh <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Ketahui lebih lanjut"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Nyahjeda apl"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Hidupkan apl kerja?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Dapatkan akses kepada apl kerja dan pemberitahuan anda"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Hidupkan"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Apl tidak tersedia"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia sekarang."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e7f5ea0..2054e47 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"အရောင်ပြင်ဆင်ခြင်း"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"လက်တစ်ဖက်သုံးမုဒ်"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ပိုမှိန်ခြင်း"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index fd96a2a..a6f945c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Kopierte tekst til utklippstavlen."</string>
     <string name="copied" msgid="4675902854553014676">"Kopiert"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> har limt inn fra utklippstavlen"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn tekst du kopierte"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn et bilde du kopierte"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn innhold du kopierte"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starter apper."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ferdigstiller oppstart."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vil du slå av skjermen?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Da du konfigurerte fingeravtrykket, trykket du på av/på-knappen.\n\nDette slår vanligvis av skjermen."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Slå av"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Avbryt"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> kjører"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Trykk for å gå tilbake til spillet"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Velg et spill"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Fargekorrigering"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndsmodus"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dimmet"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b7fc042..37ffd46 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekst naar klembord gekopieerd."</string>
     <string name="copied" msgid="4675902854553014676">"Gekopieerd"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> geplakt vanuit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft geplakt vanaf het klembord"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft door jou gekopieerde tekst geplakt"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft een door jou gekopieerde afbeelding geplakt"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft door jou gekopieerde content geplakt"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> voorbereiden."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps starten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Opstarten afronden."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Scherm uitzetten?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Toen je je vingerafdruk instelde, heb je op de aan/uit-knop gedrukt.\n\nDaarmee wordt het scherm meestal uitgezet."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Uitzetten"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Annuleren"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Tik om terug te keren naar de game"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Game kiezen"</string>
@@ -1718,8 +1713,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met één hand"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra gedimd"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
@@ -1875,10 +1869,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Geüpdatet door je beheerder"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet.\n\n"<annotation id="url">"Meer informatie"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens sturen of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet weergegeven totdat je erop tikt."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Databesparing aanzetten?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Aanzetten"</string>
@@ -1981,10 +1973,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> is nu niet beschikbaar. Dit wordt beheerd door <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Meer info"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"App niet meer onderbreken"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Werk-apps aanzetten?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Krijg toegang tot je werk-apps en meldingen"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aanzetten"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4574847..15a0531 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"ଟେକ୍ସଟ୍‍ କ୍ଲିପବୋର୍ଡକୁ କପୀ ହୋଇଯାଇଛି"</string>
     <string name="copied" msgid="4675902854553014676">"କପି କରାଗଲା"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ରୁ ପେଷ୍ଟ କରିଛି"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ କ୍ଲିପବୋର୍ଡରୁ ପେଷ୍ଟ କରିଛି"</string>
     <string name="pasted_text" msgid="4298871641549173733">"ଆପଣ କପି କରିଥିବା ଟେକ୍ସଟକୁ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ପେଷ୍ଟ କରିଛି"</string>
     <string name="pasted_image" msgid="4729097394781491022">"ଆପଣ କପି କରିଥିବା ଏକ ଛବିକୁ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ପେଷ୍ଟ କରିଛି"</string>
     <string name="pasted_content" msgid="646276353060777131">"ଆପଣ କପି କରିଥିବା ବିଷୟବସ୍ତୁକୁ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ପେଷ୍ଟ କରିଛି"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> ପ୍ରସ୍ତୁତ କରାଯାଉଛି।"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ଆପ୍‍ ଆରମ୍ଭ କରାଯାଉଛି।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ବୁଟ୍‍ ସମାପ୍ତ କରୁଛି।"</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"ସ୍କ୍ରିନ୍ ବନ୍ଦ କରିବେ?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"ଆପଣଙ୍କ ଟିପଚିହ୍ନ ସେଟ୍ ଅପ୍ କରିବା ସମୟରେ, ଆପଣ ପାୱାର ବଟନ୍ ଦବାଇଛନ୍ତି।\n\nଏହା ସାଧାରଣତଃ ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ବନ୍ଦ କରେ।"</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> ଚାଲୁଛି"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"ଗେମ୍‌କୁ ଫେରିଆସିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"ଗେମ୍ ଚୟନ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 72fe314..50e1f98 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਪਲਟਨਾ"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"ਰੰਗ ਸੁਧਾਈ"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ਇੱਕ ਹੱਥ ਮੋਡ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ਜ਼ਿਆਦਾ ਘੱਟ ਚਮਕ"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index c7f35d5..b77be3d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1028,8 +1028,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Tekst został skopiowany do schowka."</string>
     <string name="copied" msgid="4675902854553014676">"Skopiowano"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane z aplikacji <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> skopiowała dane ze schowka"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowany tekst"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowany obraz"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowane treści"</string>
@@ -1300,14 +1299,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Przygotowuję aplikację <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Uruchamianie aplikacji."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Kończenie uruchamiania."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Wyłączyć ekran?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Podczas konfigurowania odcisku palca naciśnięto przycisk zasilania.\n\nZwykle powoduje to wyłączenie ekranu."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Wyłącz"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Anuluj"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Działa <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Kliknij, by wrócić do gry"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Wybierz grę"</string>
@@ -1762,8 +1757,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcja kolorów"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tryb jednej ręki"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatkowe przyciemnienie"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index e5e9be4..bc0342a 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou conteúdo da sua área de transferência"</string>
     <string name="pasted_text" msgid="4298871641549173733">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto copiado"</string>
     <string name="pasted_image" msgid="4729097394781491022">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou uma imagem copiada"</string>
     <string name="pasted_content" msgid="646276353060777131">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o conteúdo copiado"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Desligar a tela?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Durante a configuração da sua impressão digital, você pressionou o botão liga/desliga.\n\nNormalmente, essa ação desliga a tela."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desligar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toque para voltar ao jogo"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Escolha o jogo"</string>
@@ -1874,10 +1869,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede.\n\n"<annotation id="url">"Saiba mais"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar \"Economia de dados\"?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
@@ -1980,10 +1973,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"O app <xliff:g id="APP_NAME_0">%1$s</xliff:g> não está disponível no momento. Isso é gerenciado pelo app <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Saiba mais"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Retomar app"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Ativar apps de trabalho?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Acesse seus apps e notificações de trabalho"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index cb00dce..db561c9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou da app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou a partir da área de transferência"</string>
     <string name="pasted_text" msgid="4298871641549173733">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto que copiou"</string>
     <string name="pasted_image" msgid="4729097394781491022">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou uma imagem que copiou"</string>
     <string name="pasted_content" msgid="646276353060777131">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o conteúdo que copiou"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"A preparar o <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"A iniciar aplicações"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"A concluir o arranque."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Pretende desligar o ecrã?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Quando configurou a sua impressão digital, premiu o botão ligar/desligar.\n\nGeralmente, esta ação desativa o seu ecrã."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desligar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toque para regressar ao jogo."</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Selecionar jogo"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index e5e9be4..bc0342a 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
     <string name="copied" msgid="4675902854553014676">"Copiado"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou conteúdo da sua área de transferência"</string>
     <string name="pasted_text" msgid="4298871641549173733">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto copiado"</string>
     <string name="pasted_image" msgid="4729097394781491022">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou uma imagem copiada"</string>
     <string name="pasted_content" msgid="646276353060777131">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o conteúdo copiado"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Desligar a tela?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Durante a configuração da sua impressão digital, você pressionou o botão liga/desliga.\n\nNormalmente, essa ação desliga a tela."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Desligar"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Cancelar"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Toque para voltar ao jogo"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Escolha o jogo"</string>
@@ -1874,10 +1869,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede.\n\n"<annotation id="url">"Saiba mais"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar \"Economia de dados\"?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
@@ -1980,10 +1973,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"O app <xliff:g id="APP_NAME_0">%1$s</xliff:g> não está disponível no momento. Isso é gerenciado pelo app <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Saiba mais"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Retomar app"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Ativar apps de trabalho?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Acesse seus apps e notificações de trabalho"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index cd2561a..5d38e46 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"පෙළ පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
     <string name="copied" msgid="4675902854553014676">"පිටපත් කළා"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> වෙතින් අලවන ලදි"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"ඔබගේ පසුරු පුවරුව වෙතින් <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> පිටපත් කරන ලදි"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ඔබ පිටපත් කළ පෙළ ඇලවීය"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ඔබ පිටපත් කළ රූපයක් ඇලවීය"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ඔබ පිටපත් කළ අන්තර්ගතය ඇලවීය"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> සූදානම් කරමින්."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"යෙදුම් ආරම්භ කරමින්."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ඇරඹුම අවසාන කරමින්."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"තිරය ක්‍රියාවිරහිත කරන්නද?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"ඔබගේ ඇඟිලි සලකුණ පිහිටුවන අතරතුර ඔබ බල බොත්තම එබුවේය.\n\nමෙය සාමාන්‍යයෙන් ඔබගේ තිරය ක්‍රියාවිරහිත කරයි."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"ක්‍රියාවිරහිත කරන්න"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"අවලංගු කරන්න"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> ධාවනය වෙමින්"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"ක්‍රීඩාව වෙත ආපසු යාමට තට්ටු කරන්න"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"ක්‍රීඩාව තෝරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 90f4f06..ac5483a 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1028,8 +1028,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Text bol skopírovaný do schránky."</string>
     <string name="copied" msgid="4675902854553014676">"Skopírované"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila údaje z aplikácie <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> bola prilepená zo schránky"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila text, ktorý ste skopírovali"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Aplik. <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila obrázok, ktorý ste skopírovali"</string>
     <string name="pasted_content" msgid="646276353060777131">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila obsah, ktorý ste skopírovali"</string>
@@ -1300,14 +1299,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripravuje sa aplikácia <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Prebieha spúšťanie aplikácií."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Prebieha dokončovanie spúšťania."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Chcete vypnúť obrazovku?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Pri nastavovaní odtlačku prsta ste stlačili vypínač.\n\nObrazovka sa tým zvyčajne vypne."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Vypnúť"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Zrušiť"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Spustená aplikácia: <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Klepnutím prejdete späť do hry"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Vyberte hru"</string>
@@ -1921,10 +1916,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Šetrič batérie zapne tmavý motív a obmedzí alebo vypne aktivitu na pozadí, niektoré vizuálne efekty, určité funkcie a niektoré pripojenia k sieti.\n\n"<annotation id="url">"Ďalšie informácie"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Šetrič batérie zapne tmavý motív a obmedzí alebo vypne aktivitu na pozadí, niektoré vizuálne efekty, určité funkcie a niektoré pripojenia k sieti."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"S cieľom znížiť spotrebu dát bráni šetrič dát niektorým aplikáciám odosielať alebo prijímať dáta na pozadí. Aplikácia, ktorú práve používate, môže využívať dáta, ale možno to bude robiť menej často. Môže to napríklad znamenať, že sa obrázky zobrazia, až keď na ne klepnete."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnúť šetrič dát?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnúť"</string>
@@ -2045,10 +2038,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikácia <xliff:g id="APP_NAME_0">%1$s</xliff:g> nie je momentálne k dispozícii. Spravuje to aplikácia <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Ďalšie informácie"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Znova spustiť aplikáciu"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Zapnúť pracovné aplikácie?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Získajte prístup k svojim pracovným aplikáciám a upozorneniam"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Zapnúť"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index f9dff5f..d895f74 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Teksti u kopjua në kujtesën e fragmenteve."</string>
     <string name="copied" msgid="4675902854553014676">"U kopjua"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> u ngjit nga <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjitur nga kujtesa jote e fragmenteve"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjiti një tekst që kopjove"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjiti një imazh që kopjove"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjiti një përmbajtje që kopjove"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Po përgatit <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikacionet e fillimit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Po përfundon nisjen."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Të fiket ekrani?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Gjatë konfigurimit të gjurmës së gishtit tënd, ke shtypur butonin e \"Energjisë\".\n\nKjo zakonisht fik ekranin tënd."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Fik"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Anulo"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> është në punë"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Trokit për t\'u kthyer te loja"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Zgjidh një lojë"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ee7cbb7..3512945 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1025,8 +1025,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Текст је копиран у привремену меморију."</string>
     <string name="copied" msgid="4675902854553014676">"Копирано је"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила податке из апликације <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"Садржај апликације <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепљен у привр. меморију"</string>
     <string name="pasted_text" msgid="4298871641549173733">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила текст који сте копирали"</string>
     <string name="pasted_image" msgid="4729097394781491022">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила слику коју сте копирали"</string>
     <string name="pasted_content" msgid="646276353060777131">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила садржај који сте копирали"</string>
@@ -1280,14 +1279,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"Припрема се <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Покретање апликација."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завршавање покретања."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Желите да искључите екран?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Притисли сте дугме за укључивање током подешавања отиска прста.\n\nТако се најчешће искључује екран."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Искључи"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Откажи"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Додирните да бисте се вратили у игру"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Одаберите игру"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 05aa23e..71fcb7d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1022,8 +1022,7 @@
     <string name="text_copied" msgid="2531420577879738860">"Text har kopierats till urklipp."</string>
     <string name="copied" msgid="4675902854553014676">"Kopierat"</string>
     <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
-    <!-- no translation found for pasted_from_clipboard (7355790625710831847) -->
-    <skip />
+    <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från urklipp"</string>
     <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in text som du kopierade"</string>
     <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in en bild som du kopierade"</string>
     <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in innehåll som du kopierade"</string>
@@ -1260,14 +1259,10 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> förbereds."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Appar startas."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Uppgraderingen är klar."</string>
-    <!-- no translation found for fp_enrollment_powerbutton_intent_title (3385634173366119903) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_message (6582149052513682522) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_positive_button (5963520983910436791) -->
-    <skip />
-    <!-- no translation found for fp_enrollment_powerbutton_intent_negative_button (6465764183480190748) -->
-    <skip />
+    <string name="fp_enrollment_powerbutton_intent_title" msgid="3385634173366119903">"Vill du stänga av skärmen?"</string>
+    <string name="fp_enrollment_powerbutton_intent_message" msgid="6582149052513682522">"Du tryckte på strömbrytaren när du skulle konfigurera fingeravtrycket.\n\nDet brukar leda till att skärmen stängs av."</string>
+    <string name="fp_enrollment_powerbutton_intent_positive_button" msgid="5963520983910436791">"Stäng av"</string>
+    <string name="fp_enrollment_powerbutton_intent_negative_button" msgid="6465764183480190748">"Avbryt"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Återgå till spelet genom att trycka här"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Välj spel"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 8df5d3a..663fc84 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"การแก้สี"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"โหมดมือเดียว"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"หรี่แสงเพิ่มเติม"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 69a3c06..50324d8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"单手模式"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"极暗"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 19408c2..a45f981 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1718,8 +1718,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
-    <!-- no translation found for one_handed_mode_feature_name (2334330034828094891) -->
-    <skip />
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 67da660..b983f11 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1875,10 +1875,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Kubuyekezwe umlawuli wakho"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (4877297130366222145) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (8518809702138617167) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="4877297130366222145">"Isilondolozi Sebhethri sivula itimu emnyama futhi sikhawulele noma sivale umsebenzi ongemuva, imiphumela ethile yokubuka, izakhi ezithile, nokuxhumeka kwenethiwekhi ethile.\n\n"<annotation id="url">"Funda kabanzi"</annotation></string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"Isilondolozi Sebhethri sivula ingqikithi emnyama futhi sibeke umkhawulo noma sivale umsebenzi ongemuva, imiphumela ethile yokubuka, izici ezithile, nokuxhumeka okuthile kwenethiwekhi."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Ukusiza ukwehlisa ukusetshenziswa kwedatha, iseva yedatha igwema ezinye izinhlelo zokusebenza ukuthi zithumele noma zamukele idatha ngasemuva. Uhlelo lokusebenza olisebenzisa okwamanje lingafinyelela idatha, kodwa lingenza kanjalo kancane. Lokhu kungachaza, isibonelo, ukuthi izithombe azibonisi uze uzithephe."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Vula iseva yedatha?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Vula"</string>
@@ -1981,10 +1979,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"I-<xliff:g id="APP_NAME_0">%1$s</xliff:g> ayitholakali okwamanje. Lokhu kuphethwe i-<xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Funda kabanzi"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Susa ukuphumuza uhlelo lokusebenza"</string>
-    <!-- no translation found for work_mode_off_title (961171256005852058) -->
-    <skip />
-    <!-- no translation found for work_mode_off_message (7319580997683623309) -->
-    <skip />
+    <string name="work_mode_off_title" msgid="961171256005852058">"Vula ama-app okusebenza womsebenzi?"</string>
+    <string name="work_mode_off_message" msgid="7319580997683623309">"Thola ukufinyelela kuma-app akho womsebenzi kanye nezaziso"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Vula"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Uhlelo lokusebenza alutholakali"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayitholakali khona manje."</string>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/Android.bp b/core/tests/batterystatstests/BatteryStatsViewer/Android.bp
index abac56b..6046a76 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/Android.bp
+++ b/core/tests/batterystatstests/BatteryStatsViewer/Android.bp
@@ -15,6 +15,7 @@
         "androidx.appcompat_appcompat",
         "androidx.cardview_cardview",
         "androidx.recyclerview_recyclerview",
+        "androidx.swiperefreshlayout_swiperefreshlayout",
         "com.google.android.material_material",
     ],
     platform_apis: true,
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_sum_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_sum_24.xml
new file mode 100644
index 0000000..3d29102
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_sum_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#d14d2c">
+<path
+      android:fillColor="@android:color/white"
+      android:pathData="M19,4H5v2l6,6 -6,6v2h14v-3h-9l5,-5 -5,-5h9V4z"/>
+</vector>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
index 98fc581..be0e135 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
@@ -30,7 +30,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        android:layout_marginEnd="8dp"/>
+        android:layout_marginEnd="8dp"
+        android:paddingBottom="8dp"/>
 
     <TextView
         android:id="@+id/title"
@@ -40,7 +41,7 @@
         android:textAppearance="@style/TextAppearanceBody"/>
 
     <TextView
-        android:id="@+id/amount"
+        android:id="@+id/value1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginStart="8dp"
@@ -49,7 +50,7 @@
         android:textAppearance="@style/TextAppearanceBody"/>
 
     <TextView
-        android:id="@+id/percent"
+        android:id="@+id/value2"
         android:layout_width="76dp"
         android:layout_height="wrap_content"
         android:gravity="right"
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml
deleted file mode 100644
index ecc89f0..0000000
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml
+++ /dev/null
@@ -1,33 +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.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical">
-
-    <com.google.android.material.tabs.TabLayout
-        android:id="@+id/tab_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"/>
-
-    <androidx.viewpager.widget.ViewPager
-        android:id="@+id/pager"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
-
-</LinearLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
index bea38c1..f35a210 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
@@ -14,22 +14,15 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/swipe_refresh"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
     <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/list_view"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"/>
+        android:layout_height="match_parent"/>
 
-    <ProgressBar
-        style="?android:attr/progressBarStyleLarge"
-        android:id="@+id/loading_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:indeterminate="true"/>
-</FrameLayout>
\ No newline at end of file
+</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
index 24d193c4..cf50d2a 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
@@ -14,94 +14,89 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/swipe_refresh"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
+
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <androidx.cardview.widget.CardView
-            style="@style/LoadTestCardView"
+        <LinearLayout
             android:id="@+id/app_card"
+            android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="10dp"
-            android:layout_marginEnd="10dp"
-            android:layout_marginBottom="10dp"
-            android:layout_marginStart="10dp"
-            android:padding="20dp">
+            android:visibility="invisible">
 
-            <LinearLayout
+            <androidx.cardview.widget.CardView
+                style="@style/LoadTestCardView"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:minHeight="80dp"
-                android:paddingStart="10dp"
-                android:paddingEnd="10dp">
+                android:layout_marginTop="10dp"
+                android:layout_marginEnd="10dp"
+                android:layout_marginBottom="10dp"
+                android:layout_marginStart="10dp"
+                android:padding="20dp">
 
-                <include layout="@layout/battery_consumer_info_layout"/>
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:minHeight="80dp"
+                    android:paddingStart="10dp"
+                    android:paddingEnd="10dp">
+
+                    <include layout="@layout/battery_consumer_info_layout"/>
+                </LinearLayout>
+
+            </androidx.cardview.widget.CardView>
+
+            <LinearLayout
+                android:id="@+id/headings"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="2dp"
+                android:paddingBottom="4dp">
+                <FrameLayout
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"/>
+                <TextView
+                    android:layout_width="76dp"
+                    android:layout_height="wrap_content"
+                    android:gravity="end"
+                    android:paddingEnd="20dp"
+                    android:text="Total"/>
+                <TextView
+                    android:layout_width="76dp"
+                    android:layout_height="wrap_content"
+                    android:gravity="end"
+                    android:paddingEnd="20dp"
+                    android:text="Apps"/>
             </LinearLayout>
 
-        </androidx.cardview.widget.CardView>
-
-
-        <LinearLayout
-            android:id="@+id/headings"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingTop="2dp"
-            android:paddingBottom="4dp">
-            <FrameLayout
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"/>
-            <TextView
-                android:layout_width="100dp"
-                android:layout_height="wrap_content"
-                android:gravity="end"
-                android:paddingEnd="10dp"
-                android:text="Total"/>
-            <TextView
-                android:layout_width="100dp"
-                android:layout_height="wrap_content"
-                android:gravity="end"
-                android:paddingEnd="30dp"
-                android:text="Apps"/>
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="@android:color/darker_gray"/>
         </LinearLayout>
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:background="@android:color/darker_gray"/>
-
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/battery_consumer_data_view"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="1"/>
-
-        <TextView
-            android:id="@+id/empty_view"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="center"
-            android:visibility="gone"
-            android:text="No battery stats available"/>
     </LinearLayout>
 
-    <FrameLayout
-        android:id="@+id/loading_view"
+    <TextView
+        android:id="@+id/empty_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="#AAFFFFFF">
-        <ProgressBar
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:indeterminate="true"/>
-    </FrameLayout>
-</FrameLayout>
+        android:gravity="center"
+        android:visibility="gone"
+        android:text="No battery stats available"/>
+</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index 24b164b..c207135 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -28,29 +28,54 @@
 
 public class BatteryConsumerData {
 
+    public static final String UID_BATTERY_CONSUMER_ID_PREFIX = "APP|";
+    public static final String AGGREGATE_BATTERY_CONSUMER_ID = "SYS|";
+
     enum EntryType {
-        POWER_MODELED,
-        POWER_MEASURED,
-        POWER_CUSTOM,
-        DURATION,
+        UID_TOTAL_POWER,
+        UID_POWER_MODELED,
+        UID_POWER_MEASURED,
+        UID_POWER_CUSTOM,
+        UID_DURATION,
+        DEVICE_TOTAL_POWER,
+        DEVICE_POWER_MODELED,
+        DEVICE_POWER_MEASURED,
+        DEVICE_POWER_CUSTOM,
+        DEVICE_DURATION,
+    }
+
+    enum ConsumerType {
+        UID_BATTERY_CONSUMER,
+        DEVICE_POWER_COMPONENT,
     }
 
     public static class Entry {
-        public String title;
         public EntryType entryType;
-        public double value;
-        public double total;
-        public boolean isSystemBatteryConsumer;
+        public String title;
+        public double value1;
+        public double value2;
     }
 
-    private final BatteryConsumerInfoHelper.BatteryConsumerInfo mBatteryConsumerInfo;
+    private BatteryConsumerInfoHelper.BatteryConsumerInfo mBatteryConsumerInfo;
     private final List<Entry> mEntries = new ArrayList<>();
 
     public BatteryConsumerData(Context context,
             List<BatteryUsageStats> batteryUsageStatsList, String batteryConsumerId) {
+        switch (getConsumerType(batteryConsumerId)) {
+            case UID_BATTERY_CONSUMER:
+                populateForUidBatteryConsumer(context, batteryUsageStatsList, batteryConsumerId);
+                break;
+            case DEVICE_POWER_COMPONENT:
+                populateForAggregateBatteryConsumer(context, batteryUsageStatsList);
+                break;
+        }
+    }
+
+    private void populateForUidBatteryConsumer(
+            Context context, List<BatteryUsageStats> batteryUsageStatsList,
+            String batteryConsumerId) {
         BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
         BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
-
         BatteryConsumer requestedBatteryConsumer = getRequestedBatteryConsumer(batteryUsageStats,
                 batteryConsumerId);
         BatteryConsumer requestedModeledBatteryConsumer = getRequestedBatteryConsumer(
@@ -62,7 +87,7 @@
         }
 
         mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
-                requestedBatteryConsumer, batteryConsumerId, context.getPackageManager());
+                batteryUsageStats, batteryConsumerId, context.getPackageManager());
 
         double[] totalPowerByComponentMah = new double[BatteryConsumer.POWER_COMPONENT_COUNT];
         double[] totalModeledPowerByComponentMah =
@@ -77,56 +102,152 @@
         computeTotalPowerForCustomComponent(batteryUsageStats, totalCustomPowerByComponentMah);
         computeTotalDuration(batteryUsageStats, totalDurationByComponentMs);
 
+        if (isPowerProfileModelsOnly(requestedBatteryConsumer)) {
+            addEntry("Consumed", EntryType.UID_TOTAL_POWER,
+                    requestedBatteryConsumer.getConsumedPower(),
+                    batteryUsageStats.getAggregateBatteryConsumer(
+                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+                            .getConsumedPower());
+        } else {
+            addEntry("Consumed (measured)", EntryType.UID_TOTAL_POWER,
+                    requestedBatteryConsumer.getConsumedPower(),
+                    batteryUsageStats.getAggregateBatteryConsumer(
+                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+                            .getConsumedPower());
+            addEntry("Consumed (modeled)", EntryType.UID_TOTAL_POWER,
+                    requestedModeledBatteryConsumer.getConsumedPower(),
+                    modeledBatteryUsageStats.getAggregateBatteryConsumer(
+                            BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+                            .getConsumedPower());
+        }
+
         for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
             final String metricTitle = getPowerMetricTitle(component);
             final int powerModel = requestedBatteryConsumer.getPowerModel(component);
             if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
-                addEntry(metricTitle, EntryType.POWER_MODELED,
+                addEntry(metricTitle, EntryType.UID_POWER_MODELED,
                         requestedBatteryConsumer.getConsumedPower(component),
-                        totalPowerByComponentMah[component],
-                        mBatteryConsumerInfo.isSystemBatteryConsumer);
+                        totalPowerByComponentMah[component]
+                );
             } else {
-                addEntry(metricTitle + " (measured)", EntryType.POWER_MEASURED,
+                addEntry(metricTitle + " (measured)", EntryType.UID_POWER_MEASURED,
                         requestedBatteryConsumer.getConsumedPower(component),
-                        totalPowerByComponentMah[component],
-                        mBatteryConsumerInfo.isSystemBatteryConsumer);
-                addEntry(metricTitle + " (modeled)", EntryType.POWER_MODELED,
+                        totalPowerByComponentMah[component]
+                );
+                addEntry(metricTitle + " (modeled)", EntryType.UID_POWER_MODELED,
                         requestedModeledBatteryConsumer.getConsumedPower(component),
-                        totalModeledPowerByComponentMah[component],
-                        mBatteryConsumerInfo.isSystemBatteryConsumer);
+                        totalModeledPowerByComponentMah[component]
+                );
             }
         }
 
         for (int component = 0; component < customComponentCount; component++) {
             final String name = requestedBatteryConsumer.getCustomPowerComponentName(
                     BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
-            addEntry(name + " (custom)", EntryType.POWER_CUSTOM,
+            addEntry(name + " (custom)", EntryType.UID_POWER_CUSTOM,
                     requestedBatteryConsumer.getConsumedPowerForCustomComponent(
                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
-                    totalCustomPowerByComponentMah[component],
-                    mBatteryConsumerInfo.isSystemBatteryConsumer);
+                    totalCustomPowerByComponentMah[component]
+            );
         }
 
         for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
             final String metricTitle = getTimeMetricTitle(component);
-            addEntry(metricTitle, EntryType.DURATION,
+            addEntry(metricTitle, EntryType.UID_DURATION,
                     requestedBatteryConsumer.getUsageDurationMillis(component),
-                    totalDurationByComponentMs[component],
-                    mBatteryConsumerInfo.isSystemBatteryConsumer);
+                    totalDurationByComponentMs[component]
+            );
         }
+
+        mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
+                batteryConsumerId, context.getPackageManager());
+    }
+
+    private void populateForAggregateBatteryConsumer(Context context,
+            List<BatteryUsageStats> batteryUsageStatsList) {
+        BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
+        BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
+
+        final BatteryConsumer deviceBatteryConsumer =
+                batteryUsageStats.getAggregateBatteryConsumer(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+        BatteryConsumer appsBatteryConsumer =
+                batteryUsageStats.getAggregateBatteryConsumer(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+
+        BatteryConsumer modeledDeviceBatteryConsumer =
+                modeledBatteryUsageStats.getAggregateBatteryConsumer(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+        BatteryConsumer modeledAppsBatteryConsumer =
+                modeledBatteryUsageStats.getAggregateBatteryConsumer(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+
+        if (isPowerProfileModelsOnly(deviceBatteryConsumer)) {
+            addEntry("Consumed", EntryType.DEVICE_TOTAL_POWER,
+                    deviceBatteryConsumer.getConsumedPower(),
+                    appsBatteryConsumer.getConsumedPower());
+        } else {
+            addEntry("Consumed (measured)", EntryType.DEVICE_TOTAL_POWER,
+                    deviceBatteryConsumer.getConsumedPower(),
+                    appsBatteryConsumer.getConsumedPower());
+            addEntry("Consumed (modeled)", EntryType.DEVICE_TOTAL_POWER,
+                    modeledDeviceBatteryConsumer.getConsumedPower(),
+                    modeledAppsBatteryConsumer.getConsumedPower());
+        }
+
+        mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
+                AGGREGATE_BATTERY_CONSUMER_ID, context.getPackageManager());
+
+
+        for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+            final String metricTitle = getPowerMetricTitle(component);
+            final int powerModel = deviceBatteryConsumer.getPowerModel(component);
+            if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
+                addEntry(metricTitle, EntryType.DEVICE_POWER_MODELED,
+                        deviceBatteryConsumer.getConsumedPower(component),
+                        appsBatteryConsumer.getConsumedPower(component));
+            } else {
+                addEntry(metricTitle + " (measured)", EntryType.DEVICE_POWER_MEASURED,
+                        deviceBatteryConsumer.getConsumedPower(component),
+                        appsBatteryConsumer.getConsumedPower(component));
+                addEntry(metricTitle + " (modeled)", EntryType.DEVICE_POWER_MODELED,
+                        modeledDeviceBatteryConsumer.getConsumedPower(component),
+                        modeledAppsBatteryConsumer.getConsumedPower(component));
+            }
+        }
+
+        final int customComponentCount =
+                deviceBatteryConsumer.getCustomPowerComponentCount();
+        for (int component = 0; component < customComponentCount; component++) {
+            final String name = deviceBatteryConsumer.getCustomPowerComponentName(
+                    BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
+            addEntry(name + " (custom)", EntryType.DEVICE_POWER_CUSTOM,
+                    deviceBatteryConsumer.getConsumedPowerForCustomComponent(
+                            BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
+                    appsBatteryConsumer.getConsumedPowerForCustomComponent(
+                            BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component));
+        }
+
+        for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+            final String metricTitle = getTimeMetricTitle(component);
+            addEntry(metricTitle, EntryType.DEVICE_DURATION,
+                    deviceBatteryConsumer.getUsageDurationMillis(component), 0);
+        }
+    }
+
+    private boolean isPowerProfileModelsOnly(BatteryConsumer batteryConsumer) {
+        for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+            if (batteryConsumer.getPowerModel(component)
+                    != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
+                return false;
+            }
+        }
+        return true;
     }
 
     private BatteryConsumer getRequestedBatteryConsumer(BatteryUsageStats batteryUsageStats,
             String batteryConsumerId) {
-        for (int scope = 0;
-                scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
-                scope++) {
-            if (batteryConsumerId(scope).equals(batteryConsumerId)) {
-                return batteryUsageStats.getAggregateBatteryConsumer(scope);
-            }
-        }
-
-        for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
+        for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
             if (batteryConsumerId(consumer).equals(batteryConsumerId)) {
                 return consumer;
             }
@@ -136,17 +257,27 @@
     }
 
     static String getPowerMetricTitle(int componentId) {
-        final String componentName = DebugUtils.constantToString(BatteryConsumer.class,
-                "POWER_COMPONENT_", componentId);
-        return componentName.charAt(0) + componentName.substring(1).toLowerCase().replace('_', ' ')
-                + " power";
+        return getPowerComponentName(componentId);
     }
 
     static String getTimeMetricTitle(int componentId) {
-        final String componentName = DebugUtils.constantToString(BatteryConsumer.class,
-                "POWER_COMPONENT_", componentId);
-        return componentName.charAt(0) + componentName.substring(1).toLowerCase().replace('_', ' ')
-                + " time";
+        return getPowerComponentName(componentId) + " time";
+    }
+
+    private static String getPowerComponentName(int componentId) {
+        switch (componentId) {
+            case BatteryConsumer.POWER_COMPONENT_CPU:
+                return "CPU";
+            case BatteryConsumer.POWER_COMPONENT_GNSS:
+                return "GNSS";
+            case BatteryConsumer.POWER_COMPONENT_WIFI:
+                return "Wi-Fi";
+            default:
+                String componentName = DebugUtils.constantToString(BatteryConsumer.class,
+                        "POWER_COMPONENT_", componentId);
+                return componentName.charAt(0) + componentName.substring(1).toLowerCase()
+                        .replace('_', ' ');
+        }
     }
 
     private void computeTotalPower(BatteryUsageStats batteryUsageStats,
@@ -183,14 +314,12 @@
         }
     }
 
-    private void addEntry(String title, EntryType entryType, double amount, double totalAmount,
-            boolean isSystemBatteryConsumer) {
+    private void addEntry(String title, EntryType entryType, double value1, double value2) {
         Entry entry = new Entry();
         entry.title = title;
         entry.entryType = entryType;
-        entry.value = amount;
-        entry.total = totalAmount;
-        entry.isSystemBatteryConsumer = isSystemBatteryConsumer;
+        entry.value1 = value1;
+        entry.value2 = value2;
         mEntries.add(entry);
     }
 
@@ -202,18 +331,15 @@
         return mEntries;
     }
 
-    public static String batteryConsumerId(BatteryConsumer consumer) {
-        if (consumer instanceof UidBatteryConsumer) {
-            return "APP|"
-                    + UserHandle.getUserId(((UidBatteryConsumer) consumer).getUid()) + "|"
-                    + ((UidBatteryConsumer) consumer).getUid();
-        } else {
-            return "";
+    public static ConsumerType getConsumerType(String batteryConsumerId) {
+        if (batteryConsumerId.startsWith(UID_BATTERY_CONSUMER_ID_PREFIX)) {
+            return ConsumerType.UID_BATTERY_CONSUMER;
         }
+        return ConsumerType.DEVICE_POWER_COMPONENT;
     }
 
-    public static String batteryConsumerId(
-            @BatteryUsageStats.AggregateBatteryConsumerScope int scope) {
-        return "SYS|" + scope;
+    public static String batteryConsumerId(UidBatteryConsumer consumer) {
+        return UID_BATTERY_CONSUMER_ID_PREFIX + UserHandle.getUserId(consumer.getUid()) + "|"
+                + consumer.getUid();
     }
 }
\ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
index f2d6bca..c6d71c3 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
@@ -16,18 +16,16 @@
 
 package com.android.frameworks.core.batterystatsviewer;
 
-import static com.android.frameworks.core.batterystatsviewer.BatteryConsumerData.batteryConsumerId;
-
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.os.BatteryConsumer;
 import android.os.BatteryUsageStats;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.util.DebugUtils;
 
 import androidx.annotation.NonNull;
 
+import java.util.List;
+
 class BatteryConsumerInfoHelper {
 
     private static final String SYSTEM_SERVER_PACKAGE_NAME = "android";
@@ -39,93 +37,110 @@
         public ApplicationInfo iconInfo;
         public CharSequence packages;
         public CharSequence details;
-        public boolean isSystemBatteryConsumer;
+        public BatteryConsumerData.ConsumerType consumerType;
     }
 
     @NonNull
     public static BatteryConsumerInfo makeBatteryConsumerInfo(
-            @NonNull BatteryConsumer batteryConsumer, String batteryConsumerId,
+            @NonNull BatteryUsageStats batteryUsageStats, String batteryConsumerId,
             PackageManager packageManager) {
-        BatteryConsumerInfo info = new BatteryConsumerInfo();
-        info.id = batteryConsumerId;
-        info.powerMah = batteryConsumer.getConsumedPower();
-
-        if (batteryConsumer instanceof UidBatteryConsumer) {
-            final UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
-            int uid = uidBatteryConsumer.getUid();
-            info.details = String.format("UID: %d", uid);
-            String packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain();
-            if (uid == Process.ROOT_UID) {
-                info.label = "<root>";
-            } else {
-                String[] packages = packageManager.getPackagesForUid(uid);
-                String primaryPackageName = null;
-                if (uid == Process.SYSTEM_UID) {
-                    primaryPackageName = SYSTEM_SERVER_PACKAGE_NAME;
-                } else if (packages != null) {
-                    for (String name : packages) {
-                        primaryPackageName = name;
-                        if (name.equals(packageWithHighestDrain)) {
-                            break;
-                        }
+        BatteryConsumerData.ConsumerType consumerType = BatteryConsumerData.getConsumerType(
+                batteryConsumerId);
+        switch (consumerType) {
+            case UID_BATTERY_CONSUMER:
+                final List<UidBatteryConsumer> consumers =
+                        batteryUsageStats.getUidBatteryConsumers();
+                for (UidBatteryConsumer consumer : consumers) {
+                    if (BatteryConsumerData.batteryConsumerId(consumer).equals(batteryConsumerId)) {
+                        return makeBatteryConsumerInfo(consumer, packageManager);
                     }
                 }
-
-                if (primaryPackageName != null) {
-                    try {
-                        ApplicationInfo applicationInfo =
-                                packageManager.getApplicationInfo(primaryPackageName, 0);
-                        info.label = applicationInfo.loadLabel(packageManager);
-                        info.iconInfo = applicationInfo;
-                    } catch (PackageManager.NameNotFoundException e) {
-                        info.label = primaryPackageName;
-                    }
-                } else if (packageWithHighestDrain != null) {
-                    info.label = packageWithHighestDrain;
-                }
-
-                if (packages != null && packages.length > 0) {
-                    StringBuilder sb = new StringBuilder();
-                    if (primaryPackageName != null) {
-                        sb.append(primaryPackageName);
-                    }
-                    for (String packageName : packages) {
-                        if (packageName.equals(primaryPackageName)) {
-                            continue;
-                        }
-
-                        if (sb.length() != 0) {
-                            sb.append(", ");
-                        }
-                        sb.append(packageName);
-                    }
-
-                    info.packages = sb;
-                }
-            }
-            // Default the app icon to System Server. This includes root, dex2oat and other UIDs.
-            if (info.iconInfo == null) {
-                try {
-                    info.iconInfo =
-                            packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0);
-                } catch (PackageManager.NameNotFoundException nameNotFoundException) {
-                    // Won't happen
-                }
-            }
-        } else {
-            for (int scope = 0;
-                    scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
-                    scope++) {
-                if (batteryConsumerId(scope).equals(batteryConsumerId)) {
-                    final String name = DebugUtils.constantToString(BatteryUsageStats.class,
-                            "AGGREGATE_BATTERY_CONSUMER_SCOPE_", scope)
-                            .replace('_', ' ');
-                    info.label = name;
-                    break;
-                }
-            }
+                break;
+            case DEVICE_POWER_COMPONENT:
+                return makeAggregateBatteryConsumerInfo(batteryUsageStats);
         }
 
+        BatteryConsumerInfo info = new BatteryConsumerInfo();
+        info.id = batteryConsumerId;
+        return info;
+    }
+
+    private static BatteryConsumerInfo makeBatteryConsumerInfo(
+            UidBatteryConsumer uidBatteryConsumer, PackageManager packageManager) {
+        BatteryConsumerInfo info = new BatteryConsumerInfo();
+        info.consumerType = BatteryConsumerData.ConsumerType.UID_BATTERY_CONSUMER;
+        info.id = BatteryConsumerData.batteryConsumerId(uidBatteryConsumer);
+        info.powerMah = uidBatteryConsumer.getConsumedPower();
+        int uid = uidBatteryConsumer.getUid();
+        info.details = String.format("UID: %d", uid);
+        String packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain();
+        if (uid == Process.ROOT_UID) {
+            info.label = "<root>";
+        } else {
+            String[] packages = packageManager.getPackagesForUid(uid);
+            String primaryPackageName = null;
+            if (uid == Process.SYSTEM_UID) {
+                primaryPackageName = SYSTEM_SERVER_PACKAGE_NAME;
+            } else if (packages != null) {
+                for (String name : packages) {
+                    primaryPackageName = name;
+                    if (name.equals(packageWithHighestDrain)) {
+                        break;
+                    }
+                }
+            }
+
+            if (primaryPackageName != null) {
+                try {
+                    ApplicationInfo applicationInfo =
+                            packageManager.getApplicationInfo(primaryPackageName, 0);
+                    info.label = applicationInfo.loadLabel(packageManager);
+                    info.iconInfo = applicationInfo;
+                } catch (PackageManager.NameNotFoundException e) {
+                    info.label = primaryPackageName;
+                }
+            } else if (packageWithHighestDrain != null) {
+                info.label = packageWithHighestDrain;
+            }
+
+            if (packages != null && packages.length > 0) {
+                StringBuilder sb = new StringBuilder();
+                if (primaryPackageName != null) {
+                    sb.append(primaryPackageName);
+                }
+                for (String packageName : packages) {
+                    if (packageName.equals(primaryPackageName)) {
+                        continue;
+                    }
+
+                    if (sb.length() != 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(packageName);
+                }
+
+                info.packages = sb;
+            }
+        }
+        // Default the app icon to System Server. This includes root, dex2oat and other UIDs.
+        if (info.iconInfo == null) {
+            try {
+                info.iconInfo =
+                        packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0);
+            } catch (PackageManager.NameNotFoundException nameNotFoundException) {
+                // Won't happen
+            }
+        }
+        return info;
+    }
+
+    private static BatteryConsumerInfo makeAggregateBatteryConsumerInfo(
+            BatteryUsageStats batteryUsageStats) {
+        BatteryConsumerInfo info = new BatteryConsumerInfo();
+        info.consumerType = BatteryConsumerData.ConsumerType.DEVICE_POWER_COMPONENT;
+        info.id = BatteryConsumerData.AGGREGATE_BATTERY_CONSUMER_ID;
+        info.powerMah = batteryUsageStats.getConsumedPower();
+        info.label = "Device";
         return info;
     }
 }
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
index 9e63a35..4469168 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.os.BatteryStatsManager;
 import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
 import android.os.Bundle;
 import android.os.UidBatteryConsumer;
 import android.view.LayoutInflater;
@@ -35,10 +36,12 @@
 import androidx.loader.content.Loader;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
@@ -50,10 +53,11 @@
 public class BatteryConsumerPickerActivity extends ComponentActivity {
     private static final String PREF_SELECTED_BATTERY_CONSUMER = "batteryConsumerId";
     private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
+    private static final String FORCE_FRESH_STATS = "force_fresh_stats";
     private BatteryConsumerListAdapter mBatteryConsumerListAdapter;
     private RecyclerView mAppList;
-    private View mLoadingView;
-    private final Runnable mBatteryStatsRefresh = this::loadBatteryStats;
+    private SwipeRefreshLayout mSwipeRefreshLayout;
+    private final Runnable mBatteryStatsRefresh = this::refreshPeriodically;
 
     private interface OnBatteryConsumerSelectedListener {
         void onBatteryConsumerSelected(String batteryConsumerId);
@@ -64,8 +68,11 @@
         super.onCreate(icicle);
 
         setContentView(R.layout.battery_consumer_picker_layout);
-        mLoadingView = findViewById(R.id.loading_view);
 
+        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
+        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light);
+        mSwipeRefreshLayout.setRefreshing(true);
+        mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh);
         mAppList = findViewById(R.id.list_view);
         mAppList.setLayoutManager(new LinearLayoutManager(this));
         mBatteryConsumerListAdapter =
@@ -97,7 +104,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        loadBatteryStats();
+        refreshPeriodically();
     }
 
     @Override
@@ -106,42 +113,54 @@
         getMainThreadHandler().removeCallbacks(mBatteryStatsRefresh);
     }
 
-    private void loadBatteryStats() {
-        LoaderManager.getInstance(this).restartLoader(0, null,
-                new BatteryConsumerListLoaderCallbacks());
+    private void refreshPeriodically() {
+        loadBatteryUsageStats(false);
         getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
     }
 
+    private void onRefresh() {
+        loadBatteryUsageStats(true);
+    }
+
+    private void loadBatteryUsageStats(boolean forceFreshStats) {
+        Bundle args = new Bundle();
+        args.putBoolean(FORCE_FRESH_STATS, forceFreshStats);
+        LoaderManager.getInstance(this).restartLoader(0, args,
+                new BatteryConsumerListLoaderCallbacks());
+    }
+
     private static class BatteryConsumerListLoader extends
             AsyncLoaderCompat<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> {
         private final BatteryStatsManager mBatteryStatsManager;
         private final PackageManager mPackageManager;
+        private final boolean mForceFreshStats;
 
-        BatteryConsumerListLoader(Context context) {
+        BatteryConsumerListLoader(Context context, boolean forceFreshStats) {
             super(context);
             mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
             mPackageManager = context.getPackageManager();
+            mForceFreshStats = forceFreshStats;
         }
 
         @Override
         public List<BatteryConsumerInfoHelper.BatteryConsumerInfo> loadInBackground() {
-            final BatteryUsageStats batteryUsageStats = mBatteryStatsManager.getBatteryUsageStats();
+            final BatteryUsageStatsQuery query = mForceFreshStats
+                    ? new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(0).build()
+                    : BatteryUsageStatsQuery.DEFAULT;
+            final BatteryUsageStats batteryUsageStats =
+                    mBatteryStatsManager.getBatteryUsageStats(query);
             List<BatteryConsumerInfoHelper.BatteryConsumerInfo> batteryConsumerList =
                     new ArrayList<>();
 
-            for (int scope = 0;
-                    scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
-                    scope++) {
-                batteryConsumerList.add(
-                        BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
-                                batteryUsageStats.getAggregateBatteryConsumer(scope),
-                                BatteryConsumerData.batteryConsumerId(scope),
-                                mPackageManager));
-            }
+            batteryConsumerList.add(
+                    BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
+                            batteryUsageStats,
+                            BatteryConsumerData.AGGREGATE_BATTERY_CONSUMER_ID,
+                            mPackageManager));
 
             for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
                 batteryConsumerList.add(
-                        BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer,
+                        BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
                                 BatteryConsumerData.batteryConsumerId(consumer),
                                 mPackageManager));
             }
@@ -166,7 +185,8 @@
         @Override
         public Loader<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> onCreateLoader(int id,
                 Bundle args) {
-            return new BatteryConsumerListLoader(BatteryConsumerPickerActivity.this);
+            return new BatteryConsumerListLoader(BatteryConsumerPickerActivity.this,
+                    args.getBoolean(FORCE_FRESH_STATS));
         }
 
         @Override
@@ -174,8 +194,7 @@
                 @NonNull Loader<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> loader,
                 List<BatteryConsumerInfoHelper.BatteryConsumerInfo> batteryConsumerList) {
             mBatteryConsumerListAdapter.setBatteryConsumerList(batteryConsumerList);
-            mAppList.setVisibility(View.VISIBLE);
-            mLoadingView.setVisibility(View.GONE);
+            mSwipeRefreshLayout.setRefreshing(false);
         }
 
         @Override
@@ -187,7 +206,8 @@
     public class BatteryConsumerListAdapter
             extends RecyclerView.Adapter<BatteryConsumerViewHolder> {
         private final OnBatteryConsumerSelectedListener mListener;
-        private List<BatteryConsumerInfoHelper.BatteryConsumerInfo> mBatteryConsumerList;
+        private List<BatteryConsumerInfoHelper.BatteryConsumerInfo> mBatteryConsumerList =
+                Collections.emptyList();
 
         public BatteryConsumerListAdapter(OnBatteryConsumerSelectedListener listener) {
             mListener = listener;
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
index bb75be4..33ce6bf 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
@@ -36,6 +36,7 @@
 import androidx.loader.content.Loader;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
@@ -48,10 +49,10 @@
 
     private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
     private static final int MILLIS_IN_MINUTE = 60000;
-    private static final int LOADER_BATTERY_USAGE_STATS = 1;
+    private static final String FORCE_FRESH_STATS = "force_fresh_stats";
 
     private BatteryStatsDataAdapter mBatteryStatsDataAdapter;
-    private final Runnable mBatteryStatsRefresh = this::loadBatteryStats;
+    private final Runnable mBatteryStatsRefresh = this::refreshPeriodically;
     private String mBatteryConsumerId;
     private TextView mTitleView;
     private TextView mDetailsView;
@@ -59,7 +60,8 @@
     private TextView mPackagesView;
     private View mHeadingsView;
     private RecyclerView mBatteryConsumerDataView;
-    private View mLoadingView;
+    private SwipeRefreshLayout mSwipeRefreshLayout;
+    private View mCardView;
     private View mEmptyView;
     private List<BatteryUsageStats> mBatteryUsageStats;
 
@@ -71,6 +73,12 @@
 
         setContentView(R.layout.battery_stats_viewer_layout);
 
+        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
+        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light);
+        mSwipeRefreshLayout.setRefreshing(true);
+        mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh);
+
+        mCardView = findViewById(R.id.app_card);
         mTitleView = findViewById(android.R.id.title);
         mDetailsView = findViewById(R.id.details);
         mIconView = findViewById(android.R.id.icon);
@@ -82,18 +90,13 @@
         mBatteryStatsDataAdapter = new BatteryStatsDataAdapter();
         mBatteryConsumerDataView.setAdapter(mBatteryStatsDataAdapter);
 
-        mLoadingView = findViewById(R.id.loading_view);
         mEmptyView = findViewById(R.id.empty_view);
-
-        LoaderManager loaderManager = LoaderManager.getInstance(this);
-        loaderManager.restartLoader(LOADER_BATTERY_USAGE_STATS, null,
-                new BatteryUsageStatsLoaderCallbacks());
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        loadBatteryStats();
+        refreshPeriodically();
     }
 
     @Override
@@ -102,32 +105,46 @@
         getMainThreadHandler().removeCallbacks(mBatteryStatsRefresh);
     }
 
-    private void loadBatteryStats() {
-        LoaderManager loaderManager = LoaderManager.getInstance(this);
-        loaderManager.restartLoader(LOADER_BATTERY_USAGE_STATS, null,
-                new BatteryUsageStatsLoaderCallbacks());
+    private void refreshPeriodically() {
+        loadBatteryUsageStats(false);
         getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
     }
 
+    private void onRefresh() {
+        loadBatteryUsageStats(true);
+    }
+
+    private void loadBatteryUsageStats(boolean forceFreshStats) {
+        Bundle args = new Bundle();
+        args.putBoolean(FORCE_FRESH_STATS, forceFreshStats);
+        LoaderManager.getInstance(this).restartLoader(0, args,
+                new BatteryUsageStatsLoaderCallbacks());
+    }
+
     private static class BatteryUsageStatsLoader extends
             AsyncLoaderCompat<List<BatteryUsageStats>> {
         private final BatteryStatsManager mBatteryStatsManager;
+        private final boolean mForceFreshStats;
 
-        BatteryUsageStatsLoader(Context context) {
+        BatteryUsageStatsLoader(Context context, boolean forceFreshStats) {
             super(context);
             mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
+            mForceFreshStats = forceFreshStats;
         }
 
         @Override
         public List<BatteryUsageStats> loadInBackground() {
+            final int maxStatsAgeMs = mForceFreshStats ? 0 : BATTERY_STATS_REFRESH_RATE_MILLIS;
             final BatteryUsageStatsQuery queryDefault =
                     new BatteryUsageStatsQuery.Builder()
                             .includePowerModels()
+                            .setMaxStatsAgeMs(maxStatsAgeMs)
                             .build();
             final BatteryUsageStatsQuery queryPowerProfileModeledOnly =
                     new BatteryUsageStatsQuery.Builder()
                             .powerProfileModeledOnly()
                             .includePowerModels()
+                            .setMaxStatsAgeMs(maxStatsAgeMs)
                             .build();
             return mBatteryStatsManager.getBatteryUsageStats(
                     List.of(queryDefault, queryPowerProfileModeledOnly));
@@ -143,7 +160,8 @@
         @NonNull
         @Override
         public Loader<List<BatteryUsageStats>> onCreateLoader(int id, Bundle args) {
-            return new BatteryUsageStatsLoader(BatteryStatsViewerActivity.this);
+            return new BatteryUsageStatsLoader(BatteryStatsViewerActivity.this,
+                    args.getBoolean(FORCE_FRESH_STATS));
         }
 
         @Override
@@ -194,7 +212,8 @@
                 mPackagesView.setVisibility(View.GONE);
             }
 
-            if (batteryConsumerInfo.isSystemBatteryConsumer) {
+            if (batteryConsumerInfo.consumerType
+                    == BatteryConsumerData.ConsumerType.DEVICE_POWER_COMPONENT) {
                 mHeadingsView.setVisibility(View.VISIBLE);
             } else {
                 mHeadingsView.setVisibility(View.GONE);
@@ -210,7 +229,8 @@
             mBatteryConsumerDataView.setVisibility(View.VISIBLE);
         }
 
-        mLoadingView.setVisibility(View.GONE);
+        mCardView.setVisibility(View.VISIBLE);
+        mSwipeRefreshLayout.setRefreshing(false);
     }
 
     private static class BatteryStatsDataAdapter extends
@@ -218,16 +238,16 @@
         public static class ViewHolder extends RecyclerView.ViewHolder {
             public ImageView iconImageView;
             public TextView titleTextView;
-            public TextView amountTextView;
-            public TextView percentTextView;
+            public TextView value1TextView;
+            public TextView value2TextView;
 
             ViewHolder(View itemView) {
                 super(itemView);
 
                 iconImageView = itemView.findViewById(R.id.icon);
                 titleTextView = itemView.findViewById(R.id.title);
-                amountTextView = itemView.findViewById(R.id.amount);
-                percentTextView = itemView.findViewById(R.id.percent);
+                value1TextView = itemView.findViewById(R.id.value1);
+                value2TextView = itemView.findViewById(R.id.value2);
             }
         }
 
@@ -255,57 +275,108 @@
         @Override
         public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
             BatteryConsumerData.Entry entry = mEntries.get(position);
+
             switch (entry.entryType) {
-                case POWER_MODELED:
-                    viewHolder.titleTextView.setText(entry.title);
-                    viewHolder.amountTextView.setText(
-                            String.format(Locale.getDefault(), "%.1f mAh", entry.value));
-                    viewHolder.iconImageView.setImageResource(R.drawable.gm_calculate_24);
-                    viewHolder.itemView.setBackgroundResource(
+                case UID_TOTAL_POWER:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_sum_24, 0);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setProportionText(viewHolder.value2TextView, entry);
+                    break;
+                case UID_POWER_MODELED:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_calculate_24,
                             R.color.battery_consumer_bg_power_profile);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setProportionText(viewHolder.value2TextView, entry);
                     break;
-                case POWER_MEASURED:
-                    viewHolder.titleTextView.setText(entry.title);
-                    viewHolder.amountTextView.setText(
-                            String.format(Locale.getDefault(), "%.1f mAh", entry.value));
-                    viewHolder.iconImageView.setImageResource(R.drawable.gm_amp_24);
-                    viewHolder.itemView.setBackgroundResource(
+                case UID_POWER_MEASURED:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_amp_24,
                             R.color.battery_consumer_bg_measured_energy);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setProportionText(viewHolder.value2TextView, entry);
                     break;
-                case POWER_CUSTOM:
-                    viewHolder.titleTextView.setText(entry.title);
-                    viewHolder.amountTextView.setText(
-                            String.format(Locale.getDefault(), "%.1f mAh", entry.value));
-                    viewHolder.iconImageView.setImageResource(R.drawable.gm_custom_24);
-                    viewHolder.itemView.setBackgroundResource(
+                case UID_POWER_CUSTOM:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_custom_24,
                             R.color.battery_consumer_bg_measured_energy);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setProportionText(viewHolder.value2TextView, entry);
                     break;
-                case DURATION:
-                    viewHolder.titleTextView.setText(entry.title);
-                    final long durationMs = (long) entry.value;
-                    CharSequence text;
-                    if (durationMs < MILLIS_IN_MINUTE) {
-                        text = String.format(Locale.getDefault(), "%,d ms", durationMs);
-                    } else {
-                        text = String.format(Locale.getDefault(), "%,d m %d s",
-                                durationMs / MILLIS_IN_MINUTE,
-                                (durationMs % MILLIS_IN_MINUTE) / 1000);
-                    }
-
-                    viewHolder.amountTextView.setText(text);
-                    viewHolder.iconImageView.setImageResource(R.drawable.gm_timer_24);
-                    viewHolder.itemView.setBackground(null);
+                case UID_DURATION:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_timer_24, 0);
+                    setDurationText(viewHolder.value1TextView, (long) entry.value1);
+                    setProportionText(viewHolder.value2TextView, entry);
+                    break;
+                case DEVICE_TOTAL_POWER:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_sum_24, 0);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setPowerText(viewHolder.value2TextView, entry.value2);
+                    break;
+                case DEVICE_POWER_MODELED:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_calculate_24,
+                            R.color.battery_consumer_bg_power_profile);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setPowerText(viewHolder.value2TextView, entry.value2);
+                    break;
+                case DEVICE_POWER_MEASURED:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_amp_24,
+                            R.color.battery_consumer_bg_measured_energy);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setPowerText(viewHolder.value2TextView, entry.value2);
+                    break;
+                case DEVICE_POWER_CUSTOM:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_custom_24,
+                            R.color.battery_consumer_bg_measured_energy);
+                    setPowerText(viewHolder.value1TextView, entry.value1);
+                    setPowerText(viewHolder.value2TextView, entry.value2);
+                    break;
+                case DEVICE_DURATION:
+                    setTitleIconAndBackground(viewHolder, entry.title,
+                            R.drawable.gm_timer_24, 0);
+                    setDurationText(viewHolder.value1TextView, (long) entry.value1);
+                    viewHolder.value2TextView.setVisibility(View.GONE);
                     break;
             }
+        }
 
-            double proportion;
-            if (entry.isSystemBatteryConsumer) {
-                proportion = entry.value != 0 ? entry.total * 100 / entry.value : 0;
-            } else {
-                proportion = entry.total != 0 ? entry.value * 100 / entry.total : 0;
-            }
-            viewHolder.percentTextView.setText(
+        private void setTitleIconAndBackground(ViewHolder viewHolder, String title, int icon,
+                int background) {
+            viewHolder.titleTextView.setText(title);
+            viewHolder.iconImageView.setImageResource(icon);
+            viewHolder.itemView.setBackgroundResource(background);
+        }
+
+        private void setProportionText(TextView textView, BatteryConsumerData.Entry entry) {
+            final double proportion = entry.value2 != 0 ? entry.value1 * 100 / entry.value2 : 0;
+            textView.setText(
                     String.format(Locale.getDefault(), "%.1f%%", proportion));
+            textView.setVisibility(View.VISIBLE);
+        }
+
+        private void setPowerText(TextView textView, double powerMah) {
+            textView.setText(String.format(Locale.getDefault(), "%.1f", powerMah));
+            textView.setVisibility(View.VISIBLE);
+        }
+
+        private void setDurationText(TextView textView, long durationMs) {
+            CharSequence text;
+            if (durationMs < MILLIS_IN_MINUTE) {
+                text = String.format(Locale.getDefault(), "%,d ms", durationMs);
+            } else {
+                text = String.format(Locale.getDefault(), "%,d m %d s",
+                        durationMs / MILLIS_IN_MINUTE,
+                        (durationMs % MILLIS_IN_MINUTE) / 1000);
+            }
+
+            textView.setText(text);
+            textView.setVisibility(View.VISIBLE);
         }
     }
 }
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java
new file mode 100644
index 0000000..0bbea42
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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 com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+public class SetSchemaResponseTest {
+    @Test
+    public void testRebuild() {
+        SetSchemaResponse.MigrationFailure failure1 =
+                new SetSchemaResponse.MigrationFailure(
+                        "namespace",
+                        "failure1",
+                        "schemaType",
+                        AppSearchResult.newFailedResult(
+                                AppSearchResult.RESULT_INTERNAL_ERROR, "errorMessage"));
+        SetSchemaResponse.MigrationFailure failure2 =
+                new SetSchemaResponse.MigrationFailure(
+                        "namespace",
+                        "failure2",
+                        "schemaType",
+                        AppSearchResult.newFailedResult(
+                                AppSearchResult.RESULT_INTERNAL_ERROR, "errorMessage"));
+
+        SetSchemaResponse original =
+                new SetSchemaResponse.Builder()
+                        .addDeletedType("delete1")
+                        .addIncompatibleType("incompatible1")
+                        .addMigratedType("migrated1")
+                        .addMigrationFailure(failure1)
+                        .build();
+        assertThat(original.getDeletedTypes()).containsExactly("delete1");
+        assertThat(original.getIncompatibleTypes()).containsExactly("incompatible1");
+        assertThat(original.getMigratedTypes()).containsExactly("migrated1");
+        assertThat(original.getMigrationFailures()).containsExactly(failure1);
+
+        SetSchemaResponse rebuild =
+                original.toBuilder()
+                        .addDeletedType("delete2")
+                        .addIncompatibleType("incompatible2")
+                        .addMigratedType("migrated2")
+                        .addMigrationFailure(failure2)
+                        .build();
+
+        // rebuild won't effect the original object
+        assertThat(original.getDeletedTypes()).containsExactly("delete1");
+        assertThat(original.getIncompatibleTypes()).containsExactly("incompatible1");
+        assertThat(original.getMigratedTypes()).containsExactly("migrated1");
+        assertThat(original.getMigrationFailures()).containsExactly(failure1);
+
+        assertThat(rebuild.getDeletedTypes()).containsExactly("delete1", "delete2");
+        assertThat(rebuild.getIncompatibleTypes())
+                .containsExactly("incompatible1", "incompatible2");
+        assertThat(rebuild.getMigratedTypes()).containsExactly("migrated1", "migrated2");
+        assertThat(rebuild.getMigrationFailures()).containsExactly(failure1, failure2);
+    }
+}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java b/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java
new file mode 100644
index 0000000..1774d72
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.exceptions;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+public class IllegalSchemaExceptionTest {
+    @Test
+    public void testExceptionWithMessage() {
+        IllegalSchemaException e = new IllegalSchemaException("ERROR MESSAGE");
+        assertThat(e.getMessage()).isEqualTo("ERROR MESSAGE");
+        assertThat(e).isInstanceOf(IllegalArgumentException.class);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index 127cea8..c8564ac 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -24,6 +24,7 @@
 import android.os.BatteryUsageStats;
 import android.os.Parcel;
 import android.os.UidBatteryConsumer;
+import android.os.UserBatteryConsumer;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -31,7 +32,11 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -60,13 +65,42 @@
         validateBatteryUsageStats(inBatteryUsageStats);
     }
 
+    @Test
+    public void testDump() {
+        final BatteryUsageStats stats = buildBatteryUsageStats();
+        final StringWriter out = new StringWriter();
+        try (PrintWriter pw = new PrintWriter(out)) {
+            stats.dump(pw, "  ");
+        }
+        final String dump = out.toString();
+
+        assertThat(dump).contains("Capacity: 4000");
+        assertThat(dump).contains("Computed drain: 30000");
+        assertThat(dump).contains("actual drain: 1000-2000");
+        assertThat(dump).contains("cpu: 20100 apps: 10100 duration: 20s 300ms");
+        assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms");
+        assertThat(dump).contains("UID 2000: 1200 ( screen=300 cpu=400 FOO=500 )");
+        assertThat(dump).contains("User 42: 30.0 ( cpu=10.0 FOO=20.0 )");
+    }
+
+    @Test
+    public void testPowerComponentNames_existAndUnique() {
+        Set<String> allNames = new HashSet<>();
+        for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
+            assertThat(BatteryConsumer.powerComponentIdToString(i)).isNotNull();
+            allNames.add(BatteryConsumer.powerComponentIdToString(i));
+        }
+        assertThat(allNames).hasSize(BatteryConsumer.POWER_COMPONENT_COUNT);
+    }
+
     private BatteryUsageStats buildBatteryUsageStats() {
         final MockClocks clocks = new MockClocks();
         final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
         final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(2000);
 
         final BatteryUsageStats.Builder builder =
-                new BatteryUsageStats.Builder(new String[]{"FOO"})
+                new BatteryUsageStats.Builder(new String[]{"FOO"}, true)
+                        .setBatteryCapacity(4000)
                         .setDischargePercentage(20)
                         .setDischargedPowerRange(1000, 2000)
                         .setStatsStartTimestamp(1000);
@@ -108,11 +142,22 @@
                 .setUsageDurationForCustomComponentMillis(
                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400);
 
+        builder.getOrCreateUserBatteryConsumerBuilder(42)
+                .setConsumedPower(
+                        BatteryConsumer.POWER_COMPONENT_CPU, 10)
+                .setConsumedPowerForCustomComponent(
+                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
+                .setUsageDurationMillis(
+                        BatteryConsumer.POWER_COMPONENT_CPU, 30)
+                .setUsageDurationForCustomComponentMillis(
+                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
+
         return builder.build();
     }
 
     public void validateBatteryUsageStats(BatteryUsageStats batteryUsageStats) {
         assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(30000);
+        assertThat(batteryUsageStats.getBatteryCapacity()).isEqualTo(4000);
         assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(20);
         assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(1000);
         assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(2000);
@@ -173,5 +218,26 @@
         assertThat(deviceBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
         assertThat(deviceBatteryConsumer.getCustomPowerComponentName(
                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
+
+        final List<UserBatteryConsumer> userBatteryConsumers =
+                batteryUsageStats.getUserBatteryConsumers();
+        for (UserBatteryConsumer userBatteryConsumer : userBatteryConsumers) {
+            if (userBatteryConsumer.getUserId() == 42) {
+                assertThat(userBatteryConsumer.getConsumedPower(
+                        BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10);
+                assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent(
+                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20);
+                assertThat(userBatteryConsumer.getUsageDurationMillis(
+                        BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(30);
+                assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis(
+                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(40);
+                assertThat(userBatteryConsumer.getConsumedPower()).isEqualTo(30);
+                assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
+                assertThat(userBatteryConsumer.getCustomPowerComponentName(
+                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
+            } else {
+                fail("Unexpected user ID " + userBatteryConsumer.getUserId());
+            }
+        }
     }
 }
diff --git a/data/etc/car/com.android.car.cluster.home.xml b/data/etc/car/com.android.car.cluster.home.xml
index 832e5a7..e1d2b18 100644
--- a/data/etc/car/com.android.car.cluster.home.xml
+++ b/data/etc/car/com.android.car.cluster.home.xml
@@ -17,7 +17,6 @@
 <permissions>
     <privapp-permissions package="com.android.car.cluster.home">
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
-        <permission name="android.car.permission.ACCESS_PRIVATE_DISPLAY_ID"/>
         <permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/car/com.android.carsystemui.xml b/data/etc/car/com.android.carsystemui.xml
index 8c05282..a267d56 100644
--- a/data/etc/car/com.android.carsystemui.xml
+++ b/data/etc/car/com.android.carsystemui.xml
@@ -19,6 +19,7 @@
         <permission name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
         <permission name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/>
         <permission name="android.car.permission.CAR_ENROLL_TRUST"/>
+        <permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
         <permission name="android.car.permission.CAR_POWER"/>
         <permission name="android.car.permission.CONTROL_CAR_CLIMATE"/>
         <permission name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY"/>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index bbbbe69..26f98d8 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -33,9 +33,6 @@
     <!-- Allow PIP to resize via dragging the corner of PiP. -->
     <bool name="config_pipEnableDragCornerResize">false</bool>
 
-    <!-- Allow PIP to enable round corner, see also R.dimen.pip_corner_radius -->
-    <bool name="config_pipEnableRoundCorner">false</bool>
-
     <!-- Animation duration when using long press on recents to dock -->
     <integer name="long_press_dock_anim_duration">250</integer>
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
index 2569b78..b4c745f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
@@ -24,4 +24,12 @@
      * Notifies the listener that the Pip animation is started.
      */
     void onPipAnimationStarted();
+
+    /**
+     * Notifies the listener about PiP round corner radius changes.
+     * Listener can expect an immediate callback the first time they attach.
+     *
+     * @param cornerRadius the pixel value of the corner radius, zero means it's disabled.
+     */
+    void onPipCornerRadiusChanged(int cornerRadius);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 2b79539..319d57a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -17,7 +17,6 @@
 package com.android.wm.shell.pip;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -30,10 +29,6 @@
  * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
  */
 public class PipSurfaceTransactionHelper {
-
-    private final boolean mEnableCornerRadius;
-    private int mCornerRadius;
-
     /** for {@link #scale(SurfaceControl.Transaction, SurfaceControl, Rect, Rect)} operation */
     private final Matrix mTmpTransform = new Matrix();
     private final float[] mTmpFloat9 = new float[9];
@@ -41,11 +36,7 @@
     private final RectF mTmpDestinationRectF = new RectF();
     private final Rect mTmpDestinationRect = new Rect();
 
-    public PipSurfaceTransactionHelper(Context context) {
-        final Resources res = context.getResources();
-        mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner)
-            || SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false);
-    }
+    private int mCornerRadius;
 
     /**
      * Called when display size or font size of settings changed
@@ -53,10 +44,10 @@
      * @param context the current context
      */
     public void onDensityOrFontScaleChanged(Context context) {
-        if (mEnableCornerRadius) {
-            final Resources res = context.getResources();
-            mCornerRadius = res.getDimensionPixelSize(R.dimen.pip_corner_radius);
-        }
+        final boolean enableCornerRadius =
+                SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false);
+        mCornerRadius = enableCornerRadius
+                ? context.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius) : 0;
     }
 
     /**
@@ -194,9 +185,7 @@
      */
     public PipSurfaceTransactionHelper round(SurfaceControl.Transaction tx, SurfaceControl leash,
             boolean applyCornerRadius) {
-        if (mEnableCornerRadius) {
-            tx.setCornerRadius(leash, applyCornerRadius ? mCornerRadius : 0);
-        }
+        tx.setCornerRadius(leash, applyCornerRadius ? mCornerRadius : 0);
         return this;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index fa5caf0..29a483b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -36,6 +36,7 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
@@ -50,6 +51,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayChangeController;
 import com.android.wm.shell.common.DisplayController;
@@ -428,6 +430,7 @@
 
     private void onDensityOrFontScaleChanged() {
         mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext);
+        onPipCornerRadiusChanged();
     }
 
     private void onOverlayChanged() {
@@ -488,10 +491,6 @@
         mTouchHandler.getMotionHelper().expandLeavePip(false /* skipAnimation */);
     }
 
-    private PipTouchHandler getPipTouchHandler() {
-        return mTouchHandler;
-    }
-
     /**
      * Hides the PIP menu.
      */
@@ -531,6 +530,21 @@
 
     private void setPinnedStackAnimationListener(IPipAnimationListener callback) {
         mPinnedStackAnimationRecentsCallback = callback;
+        onPipCornerRadiusChanged();
+    }
+
+    private void onPipCornerRadiusChanged() {
+        if (mPinnedStackAnimationRecentsCallback != null) {
+            final boolean enableCornerRadius =
+                    SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false);
+            final int cornerRadius = enableCornerRadius
+                    ? mContext.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius) : 0;
+            try {
+                mPinnedStackAnimationRecentsCallback.onPipCornerRadiusChanged(cornerRadius);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to call onPipCornerRadiusChanged", e);
+            }
+        }
     }
 
     private Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 2b45346..ecbf0f1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -152,9 +152,8 @@
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         inflate(context, R.layout.pip_menu, this);
 
-        final boolean enableCornerRadius = mContext.getResources()
-                .getBoolean(R.bool.config_pipEnableRoundCorner)
-                || SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false);
+        final boolean enableCornerRadius =
+                SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false);
         mBackgroundDrawable = enableCornerRadius
                 ? mContext.getDrawable(R.drawable.pip_menu_background)
                 : new ColorDrawable(Color.BLACK);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 8fa2236..a1e6832 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -17,7 +17,6 @@
 package com.android.wm.shell.startingsurface;
 
 import static android.content.Context.CONTEXT_RESTRICTED;
-import static android.content.res.Configuration.EMPTY;
 import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
 import static android.view.Display.DEFAULT_DISPLAY;
 
@@ -54,7 +53,6 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
 
-import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 /**
@@ -92,8 +90,6 @@
  * => makeSplashScreenContentView -> cachePaint(=AdaptiveIconDrawable#draw)
  * => WM#addView -> .. waiting for Choreographer#doFrame -> relayout -> draw -> (draw the Paint
  * directly).
- *
- * @hide
  */
 public class StartingSurfaceDrawer {
     static final String TAG = StartingSurfaceDrawer.class.getSimpleName();
@@ -197,7 +193,7 @@
         }
 
         final Configuration taskConfig = taskInfo.getConfiguration();
-        if (taskConfig != null && !taskConfig.equals(EMPTY)) {
+        if (taskConfig.diffPublicOnly(context.getResources().getConfiguration()) != 0) {
             if (DEBUG_SPLASH_SCREEN) {
                 Slog.d(TAG, "addSplashScreen: creating context based"
                         + " on task Configuration " + taskConfig + " for splash screen");
@@ -226,20 +222,11 @@
             typedArray.recycle();
         }
 
-        int windowFlags = 0;
-        windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-
-        final boolean[] showWallpaper = new boolean[1];
-        getWindowResFromContext(context, a ->
-                showWallpaper[0] = a.getBoolean(R.styleable.Window_windowShowWallpaper, false));
-        if (showWallpaper[0]) {
-            windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-        }
-
         final PhoneWindow win = new PhoneWindow(context);
         win.setIsStartingWindow(true);
 
-        CharSequence label = context.getResources().getText(labelRes, null);
+        final Resources res = context.getResources();
+        final CharSequence label = res.getText(labelRes, null);
         // Only change the accessibility title if the label is localized
         if (label != null) {
             win.setTitle(label, true);
@@ -247,7 +234,12 @@
             win.setTitle(nonLocalizedLabel, false);
         }
 
-        win.setType(WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+        int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
+        if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
+            windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+        }
+        a.recycle();
 
         // Assumes it's safe to show starting windows of launched apps while
         // the keyguard is being hidden. This is okay because starting windows never show
@@ -261,24 +253,20 @@
         // touchable or focusable by the user.  We also add in the ALT_FOCUSABLE_IM
         // flag because we do know that the next window will take input
         // focus, so we want to get the IME window up on top of us right away.
-        win.setFlags(windowFlags
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                windowFlags
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+        windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        win.setFlags(windowFlags, windowFlags);
 
         final int iconRes = activityInfo.getIconResource();
         final int logoRes = activityInfo.getLogoResource();
         win.setDefaultIcon(iconRes);
         win.setDefaultLogo(logoRes);
 
-        win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.MATCH_PARENT);
-
         final WindowManager.LayoutParams params = win.getAttributes();
+        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+        params.height = WindowManager.LayoutParams.MATCH_PARENT;
         params.token = appToken;
         params.packageName = activityInfo.packageName;
         params.windowAnimations = win.getWindowStyle().getResourceId(
@@ -289,10 +277,7 @@
         params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
         params.format = PixelFormat.RGBA_8888;
 
-        final Resources res = context.getResources();
-        final boolean supportsScreen = res != null && (res.getCompatibilityInfo() != null
-                && res.getCompatibilityInfo().supportsScreen());
-        if (!supportsScreen) {
+        if (!res.getCompatibilityInfo().supportsScreen()) {
             params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
         }
 
@@ -337,7 +322,7 @@
 
         try {
             final View view = win.getDecorView();
-            final WindowManager wm = mContext.getSystemService(WindowManager.class);
+            final WindowManager wm = context.getSystemService(WindowManager.class);
             postAddWindow(taskId, appToken, view, wm, params);
 
             // We use the splash screen worker thread to create SplashScreenView while adding the
@@ -505,12 +490,6 @@
         }
     }
 
-    private void getWindowResFromContext(Context ctx, Consumer<TypedArray> consumer) {
-        final TypedArray a = ctx.obtainStyledAttributes(R.styleable.Window);
-        consumer.accept(a);
-        a.recycle();
-    }
-
     /**
      * Record the view or surface for a starting window.
      */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 882d382..8ef1df6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -68,7 +68,7 @@
     @Before
     public void setUp() throws Exception {
         mPipAnimationController = new PipAnimationController(
-                new PipSurfaceTransactionHelper(mContext));
+                new PipSurfaceTransactionHelper());
         mLeash = new SurfaceControl.Builder()
                 .setContainerLayer()
                 .setName("FakeLeash")
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 94fe243..a164233 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -150,9 +150,19 @@
     }
 }
 
+static inline void applyMatrix(const SkMatrix& transform, SkRect* rect) {
+    return applyMatrix(&transform, rect);
+}
+
 static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRect* out) {
     if (in.isEmpty()) return;
     SkRect temp(in);
+    if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) {
+        const StretchEffect& stretch = props.layerProperties().getStretchEffect();
+        if (!stretch.isEmpty()) {
+            applyMatrix(stretch.makeLinearStretch(props.getWidth(), props.getHeight()), &temp);
+        }
+    }
     applyMatrix(props.getTransformMatrix(), &temp);
     if (props.getStaticMatrix()) {
         applyMatrix(props.getStaticMatrix(), &temp);
@@ -272,18 +282,21 @@
 
 DamageAccumulator::StretchResult DamageAccumulator::findNearestStretchEffect() const {
     DirtyStack* frame = mHead;
+    const auto& headProperties = mHead->renderNode->properties();
+    float startWidth = headProperties.getWidth();
+    float startHeight = headProperties.getHeight();
     while (frame->prev != frame) {
         if (frame->type == TransformRenderNode) {
             const auto& renderNode = frame->renderNode;
             const auto& frameRenderNodeProperties = renderNode->properties();
             const auto& effect =
                     frameRenderNodeProperties.layerProperties().getStretchEffect();
-            const float width = (float) renderNode->getWidth();
-            const float height = (float) renderNode->getHeight();
+            const float width = (float) frameRenderNodeProperties.getWidth();
+            const float height = (float) frameRenderNodeProperties.getHeight();
             if (!effect.isEmpty()) {
                 Matrix4 stretchMatrix;
                 computeTransformImpl(mHead, frame, &stretchMatrix);
-                Rect stretchRect = Rect(0.f, 0.f, width, height);
+                Rect stretchRect = Rect(0.f, 0.f, startWidth, startHeight);
                 stretchMatrix.mapRect(stretchRect);
 
                 return StretchResult{
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 7af0a22..9ed801b 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -84,6 +84,8 @@
 bool Properties::useHintManager = true;
 int Properties::targetCpuTimePercentage = 70;
 
+StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI;
+
 bool Properties::load() {
     bool prevDebugLayersUpdates = debugLayersUpdates;
     bool prevDebugOverdraw = debugOverdraw;
@@ -135,6 +137,10 @@
     targetCpuTimePercentage = base::GetIntProperty(PROPERTY_TARGET_CPU_TIME_PERCENTAGE, 70);
     if (targetCpuTimePercentage <= 0 || targetCpuTimePercentage > 100) targetCpuTimePercentage = 70;
 
+    int stretchType = base::GetIntProperty(PROPERTY_STRETCH_EFFECT_TYPE, 0);
+    stretchType = std::clamp(stretchType, 0, static_cast<int>(StretchEffectBehavior::LinearScale));
+    stretchEffectBehavior = static_cast<StretchEffectBehavior>(stretchType);
+
     return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
 }
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 1cb87be..9d2b617 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -171,6 +171,8 @@
  */
 #define PROPERTY_TARGET_CPU_TIME_PERCENTAGE "debug.hwui.target_cpu_time_percent"
 
+#define PROPERTY_STRETCH_EFFECT_TYPE "debug.hwui.stretch_mode"
+
 /**
  * Property for whether this is running in the emulator.
  */
@@ -178,7 +180,7 @@
 
 /**
  * Turns on the Skia GPU option "reduceOpsTaskSplitting" which improves GPU
- * efficiency but may increase VRAM consumption. Default is "false".
+ * efficiency but may increase VRAM consumption. Default is "true".
  */
 #define PROPERTY_REDUCE_OPS_TASK_SPLITTING "renderthread.skia.reduceopstasksplitting"
 
@@ -197,6 +199,12 @@
 
 enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 };
 
+enum class StretchEffectBehavior {
+    ShaderHWUI, // Stretch shader in HWUI only, matrix scale in SF
+    Shader, // Stretch shader in both HWUI and SF
+    LinearScale // Linear stretch everywhere
+};
+
 /**
  * Renderthread-only singleton which manages several static rendering properties. Most of these
  * are driven by system properties which are queried once at initialization, and again if init()
@@ -270,6 +278,8 @@
     static bool useHintManager;
     static int targetCpuTimePercentage;
 
+    static StretchEffectBehavior stretchEffectBehavior;
+
 private:
     static ProfileType sProfileType;
     static bool sDisableProfileBars;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index fce2e1f..64abd94 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -477,6 +477,14 @@
             }
         }
     }
+
+    if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) {
+        const StretchEffect& stretch = properties().layerProperties().getStretchEffect();
+        if (!stretch.isEmpty()) {
+            matrix.multiply(
+                    stretch.makeLinearStretch(properties().getWidth(), properties().getHeight()));
+        }
+    }
 }
 
 const SkPath* RenderNode::getClippedOutline(const SkRect& clipRect) const {
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index 1519d69..0599bfa 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -68,9 +68,8 @@
     // and the other way around.
     uniform float uInterpolationStrength;
 
-    float easeInCubic(float t, float d) {
-        float tmp = t * d;
-        return tmp * tmp * tmp;
+    float easeIn(float t, float d) {
+        return t * d;
     }
 
     float computeOverscrollStart(
@@ -83,7 +82,7 @@
     ) {
         float offsetPos = uStretchAffectedDist - inPos;
         float posBasedVariation = mix(
-                1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
+                1. ,easeIn(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
         float stretchIntensity = overscroll * posBasedVariation;
         return distanceStretched - (offsetPos / (1. + stretchIntensity));
     }
@@ -99,7 +98,7 @@
     ) {
         float offsetPos = inPos - reverseStretchDist;
         float posBasedVariation = mix(
-                1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
+                1. ,easeIn(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
         float stretchIntensity = (-overscroll) * posBasedVariation;
         return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity)));
     }
@@ -234,4 +233,80 @@
     return instance.effect;
 }
 
+/**
+ * Helper method that maps the input texture position to the stretch position
+ * based on the given overscroll value that represents an overscroll from
+ * either the top or left
+ * @param overscroll current overscroll value
+ * @param input normalized input position (can be x or y) on the input texture
+ * @return stretched position of the input normalized from 0 to 1
+ */
+float reverseMapStart(float overscroll, float input) {
+    float numerator = (-input * overscroll * overscroll) -
+        (2 * input * overscroll) - input;
+    float denominator = 1.f + (.3f * overscroll) +
+        (.7f * input * overscroll * overscroll) + (.7f * input * overscroll);
+    return -(numerator / denominator);
+}
+
+/**
+ * Helper method that maps the input texture position to the stretch position
+ * based on the given overscroll value that represents an overscroll from
+ * either the bottom or right
+ * @param overscroll current overscroll value
+ * @param input normalized input position (can be x or y) on the input texture
+ * @return stretched position of the input normalized from 0 to 1
+ */
+float reverseMapEnd(float overscroll, float input) {
+    float numerator = (.3f * overscroll * overscroll) -
+        (.3f * input * overscroll * overscroll) +
+        (1.3f * input * overscroll) - overscroll - input;
+    float denominator = (.7f * input * overscroll * overscroll) -
+        (.7f * input * overscroll) - (.7f * overscroll * overscroll) +
+        overscroll - 1.f;
+    return numerator / denominator;
+}
+
+/**
+  * Calculates the normalized stretch position given the normalized input
+  * position. This handles calculating the overscroll from either the
+  * top or left vs bottom or right depending on the sign of the given overscroll
+  * value
+  *
+  * @param overscroll unit vector of overscroll from -1 to 1 indicating overscroll
+  * from the bottom or right vs top or left respectively
+  * @param normalizedInput the
+  * @return
+  */
+float computeReverseOverscroll(float overscroll, float normalizedInput) {
+    float distanceStretched = 1.f / (1.f + abs(overscroll));
+    float distanceDiff = distanceStretched - 1.f;
+    if (overscroll > 0) {
+        float output = reverseMapStart(overscroll, normalizedInput);
+        if (output <= 1.0f) {
+            return output;
+        } else if (output >= distanceStretched){
+            return output - distanceDiff;
+        }
+    }
+
+    if (overscroll < 0) {
+        float output = reverseMapEnd(overscroll, normalizedInput);
+        if (output >= 0.f) {
+            return output;
+        } else if (output < 0.f){
+            return output + distanceDiff;
+        }
+    }
+    return normalizedInput;
+}
+
+float StretchEffect::computeStretchedPositionX(float normalizedX) const {
+  return computeReverseOverscroll(mStretchDirection.x(), normalizedX);
+}
+
+float StretchEffect::computeStretchedPositionY(float normalizedY) const {
+  return computeReverseOverscroll(mStretchDirection.y(), normalizedY);
+}
+
 } // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
index 61537f0..c49d53a 100644
--- a/libs/hwui/effects/StretchEffect.h
+++ b/libs/hwui/effects/StretchEffect.h
@@ -20,6 +20,7 @@
 
 #include <SkImage.h>
 #include <SkImageFilter.h>
+#include <SkMatrix.h>
 #include <SkPoint.h>
 #include <SkRect.h>
 #include <SkRuntimeEffect.h>
@@ -75,6 +76,22 @@
         maxStretchAmountY = std::max(maxStretchAmountY, other.maxStretchAmountY);
     }
 
+    /**
+     * Return the stretched x position given the normalized x position with
+     * the current horizontal stretch direction
+     * @param normalizedX x position on the input texture from 0 to 1
+     * @return x position when the horizontal stretch direction applied
+     */
+    float computeStretchedPositionX(float normalizedX) const;
+
+    /**
+     * Return the stretched y position given the normalized y position with
+     * the current horizontal stretch direction
+     * @param normalizedX y position on the input texture from 0 to 1
+     * @return y position when the horizontal stretch direction applied
+     */
+    float computeStretchedPositionY(float normalizedY) const;
+
     sk_sp<SkShader> getShader(float width, float height,
                               const sk_sp<SkImage>& snapshotImage) const;
 
@@ -83,6 +100,14 @@
 
     const SkVector getStretchDirection() const { return mStretchDirection; }
 
+    SkMatrix makeLinearStretch(float width, float height) const {
+        SkMatrix matrix;
+        auto [sX, sY] = getStretchDirection();
+        matrix.setScale(1 + std::abs(sX), 1 + std::abs(sY), sX > 0 ? 0 : width,
+                        sY > 0 ? 0 : height);
+        return matrix;
+    }
+
 private:
     static sk_sp<SkRuntimeEffect> getStretchEffect();
     mutable SkVector mStretchDirection{0, 0};
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 5131c64..cd0783f 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -572,11 +572,13 @@
             info.damageAccumulator->computeCurrentTransform(&transform);
             const RenderProperties& props = node.properties();
 
-            if (info.stretchEffectCount) {
-                handleStretchEffect(info, transform);
+            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
+            bool useStretchShader = Properties::stretchEffectBehavior !=
+                StretchEffectBehavior::LinearScale;
+            if (useStretchShader && info.stretchEffectCount) {
+                handleStretchEffect(info, bounds);
             }
 
-            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
             transform.mapRect(bounds);
 
             if (CC_LIKELY(transform.isPureTranslate())) {
@@ -639,7 +641,33 @@
             return env;
         }
 
-        void handleStretchEffect(const TreeInfo& info, const Matrix4& transform) {
+        void stretchTargetBounds(const StretchEffect& stretchEffect,
+                                 float width, float height,
+                                 const SkRect& childRelativeBounds,
+                                 uirenderer::Rect& bounds) {
+              float normalizedLeft = childRelativeBounds.left() / width;
+              float normalizedTop = childRelativeBounds.top() / height;
+              float normalizedRight = childRelativeBounds.right() / width;
+              float normalizedBottom = childRelativeBounds.bottom() / height;
+              float reverseLeft = width *
+                  (stretchEffect.computeStretchedPositionX(normalizedLeft) -
+                    normalizedLeft);
+              float reverseTop = height *
+                  (stretchEffect.computeStretchedPositionY(normalizedTop) -
+                    normalizedTop);
+              float reverseRight = width *
+                  (stretchEffect.computeStretchedPositionX(normalizedRight) -
+                    normalizedLeft);
+              float reverseBottom = height *
+                  (stretchEffect.computeStretchedPositionY(normalizedBottom) -
+                    normalizedTop);
+              bounds.left = reverseLeft;
+              bounds.top = reverseTop;
+              bounds.right = reverseRight;
+              bounds.bottom = reverseBottom;
+        }
+
+        void handleStretchEffect(const TreeInfo& info, uirenderer::Rect& targetBounds) {
             // Search up to find the nearest stretcheffect parent
             const DamageAccumulator::StretchResult result =
                 info.damageAccumulator->findNearestStretchEffect();
@@ -649,31 +677,35 @@
             }
 
             const auto& childRelativeBounds = result.childRelativeBounds;
+            stretchTargetBounds(*effect, result.width, result.height,
+                                childRelativeBounds,targetBounds);
 
-            JNIEnv* env = jnienv();
+            if (Properties::stretchEffectBehavior == StretchEffectBehavior::Shader) {
+                JNIEnv* env = jnienv();
 
-            jobject localref = env->NewLocalRef(mWeakRef);
-            if (CC_UNLIKELY(!localref)) {
-                env->DeleteWeakGlobalRef(mWeakRef);
-                mWeakRef = nullptr;
-                return;
-            }
+                jobject localref = env->NewLocalRef(mWeakRef);
+                if (CC_UNLIKELY(!localref)) {
+                    env->DeleteWeakGlobalRef(mWeakRef);
+                    mWeakRef = nullptr;
+                    return;
+                }
 #ifdef __ANDROID__  // Layoutlib does not support CanvasContext
-            SkVector stretchDirection = effect->getStretchDirection();
-            env->CallVoidMethod(localref, gPositionListener_ApplyStretchMethod,
-                                info.canvasContext.getFrameNumber(),
-                                result.width,
-                                result.height,
-                                stretchDirection.fX,
-                                stretchDirection.fY,
-                                effect->maxStretchAmountX,
-                                effect->maxStretchAmountY,
-                                childRelativeBounds.left(),
-                                childRelativeBounds.top(),
-                                childRelativeBounds.right(),
-                                childRelativeBounds.bottom());
+                SkVector stretchDirection = effect->getStretchDirection();
+                env->CallVoidMethod(localref, gPositionListener_ApplyStretchMethod,
+                                    info.canvasContext.getFrameNumber(),
+                                    result.width,
+                                    result.height,
+                                    stretchDirection.fX,
+                                    stretchDirection.fY,
+                                    effect->maxStretchAmountX,
+                                    effect->maxStretchAmountY,
+                                    childRelativeBounds.left(),
+                                    childRelativeBounds.top(),
+                                    childRelativeBounds.right(),
+                                    childRelativeBounds.bottom());
 #endif
-            env->DeleteLocalRef(localref);
+                env->DeleteLocalRef(localref);
+            }
         }
 
         void doUpdatePositionAsync(jlong frameNumber, jint left, jint top,
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 1ae06d0..57cdde2 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -171,11 +171,16 @@
     displayList->mProjectedOutline = nullptr;
 }
 
+static bool stretchNeedsLayer(const LayerProperties& properties) {
+    return Properties::stretchEffectBehavior != StretchEffectBehavior::LinearScale &&
+           !properties.getStretchEffect().isEmpty();
+}
+
 static bool layerNeedsPaint(const sk_sp<SkImage>& snapshotImage, const LayerProperties& properties,
                             float alphaMultiplier, SkPaint* paint) {
     if (alphaMultiplier < 1.0f || properties.alpha() < 255 ||
         properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr ||
-        properties.getImageFilter() != nullptr || !properties.getStretchEffect().isEmpty()) {
+        properties.getImageFilter() != nullptr || stretchNeedsLayer(properties)) {
         paint->setAlpha(properties.alpha() * alphaMultiplier);
         paint->setBlendMode(properties.xferMode());
         paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
@@ -247,7 +252,8 @@
             }
 
             const StretchEffect& stretch = properties.layerProperties().getStretchEffect();
-            if (stretch.isEmpty()) {
+            if (stretch.isEmpty() ||
+                Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) {
                 // If we don't have any stretch effects, issue the filtered
                 // canvas draw calls to make sure we still punch a hole
                 // with the same canvas transformation + clip into the target
@@ -326,6 +332,13 @@
             canvas->concat(*properties.getTransformMatrix());
         }
     }
+    if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) {
+        const StretchEffect& stretch = properties.layerProperties().getStretchEffect();
+        if (!stretch.isEmpty()) {
+            canvas->concat(
+                    stretch.makeLinearStretch(properties.getWidth(), properties.getHeight()));
+        }
+    }
     const bool isLayer = properties.effectiveLayerType() != LayerType::None;
     int clipFlags = properties.getClippingFlags();
     if (properties.getAlpha() < 1) {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 04aa1cb..3421e01 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -275,7 +275,7 @@
 void RenderThread::initGrContextOptions(GrContextOptions& options) {
     options.fPreferExternalImagesOverES3 = true;
     options.fDisableDistanceFieldPaths = true;
-    if (android::base::GetBoolProperty(PROPERTY_REDUCE_OPS_TASK_SPLITTING, false)) {
+    if (android::base::GetBoolProperty(PROPERTY_REDUCE_OPS_TASK_SPLITTING, true)) {
         options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kYes;
     } else {
         options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index 27c7eda..1456f74 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -28,6 +28,19 @@
  * same signal transmission time {@link GnssMeasurement#getReceivedSvTimeNanos()}.
  *
  * <p>The position and velocity must be in ECEF coordinates.
+ *
+ * <p>If {@link GnssMeasurement#getSatellitePvt()} is derived from Broadcast ephemeris, then the
+ * position is already w.r.t. the antenna phase center. However, if
+ * {@link GnssMeasurement#getSatellitePvt()} is derived from other modeled orbits, such as
+ * long-term orbits, or precise orbits, then the orbits may have been computed w.r.t.
+ * the satellite center of mass, and then GNSS vendors are expected to correct for the effect
+ * on different phase centers (can differ by meters) of different GNSS signals (e.g. L1, L5)
+ * on the reported satellite position. Accordingly, we might observe a different satellite
+ * position reported for L1 GnssMeasurement struct compared to L5 GnssMeasurement struct.
+ *
+ * <p>If {@link GnssMeasurement#getReceivedSvTimeNanos()} is not fully decoded,
+ * {@link GnssMeasurement#getSatellitePvt()} could still be reported and
+ * {@link GnssMeasurement#getReceivedSvTimeUncertaintyNanos()} would be used to provide confidence.
  * @hide
  */
 @SystemApi
@@ -203,7 +216,7 @@
         /**
          * Returns the signal in Space User Range Error Rate (URE Rate) (meters per second).
          *
-         * It covers satellite velocity error and Satellite clock drift
+         * <p>It covers satellite velocity error and Satellite clock drift
          * projected to the pseudorange rate measurements.
          */
         @FloatRange(from = 0.0f, fromInclusive = false)
@@ -272,6 +285,14 @@
         /**
          * Returns the satellite hardware code bias of the reported code type w.r.t
          * ionosphere-free measurement in meters.
+         *
+         * <p>When broadcast ephemeris is used, this is the offset caused
+         * by the satellite hardware delays at different frequencies;
+         * e.g. in IS-GPS-705D, this term is described in Section
+         * 20.3.3.3.1.2.1.
+         *
+         * <p>For GPS this term is ~10ns, and affects the satellite position
+         * computation by less than a millimeter.
          */
         @FloatRange()
         public double getHardwareCodeBiasMeters() {
@@ -282,6 +303,17 @@
          * Returns the satellite time correction for ionospheric-free signal measurement
          * (meters). The satellite clock correction for the given signal type
          * = satTimeCorrectionMeters - satHardwareCodeBiasMeters.
+         *
+         * <p>When broadcast ephemeris is used, this is the offset modeled in the
+         * clock terms broadcast over the air by the satellites;
+         * e.g. in IS-GPS-200H, Section 20.3.3.3.3.1, this term is
+         * ∆tsv = af0 + af1(t - toc) + af2(t - toc)^2 + ∆tr.
+         *
+         * <p>If another source of ephemeris is used for SatellitePvt, then the
+         * equivalent value of satTimeCorrection must be provided.
+         *
+         * <p>For GPS this term is ~1ms, and affects the satellite position
+         * computation by ~1m.
          */
         @FloatRange()
         public double getTimeCorrectionMeters() {
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 8fee768..c8412f2 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -518,13 +518,13 @@
      * @hide
      */
     // never unhide
-    public static final int SAMPLE_RATE_HZ_MIN = 4000;
+    public static final int SAMPLE_RATE_HZ_MIN = AudioSystem.SAMPLE_RATE_HZ_MIN;
     /** Maximum value for sample rate,
      *  assuming AudioTrack and AudioRecord share the same limitations.
      * @hide
      */
     // never unhide
-    public static final int SAMPLE_RATE_HZ_MAX = 192000;
+    public static final int SAMPLE_RATE_HZ_MAX = AudioSystem.SAMPLE_RATE_HZ_MAX;
     /** Sample rate will be a route-dependent value.
      * For AudioTrack, it is usually the sink sample rate,
      * and for AudioRecord it is usually the source sample rate.
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index ce9d7e3..39b7922 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -105,11 +105,31 @@
      */
     public static final int NUM_STREAMS = 5;
 
-    /** Maximum value for AudioTrack channel count
-     * @hide public for MediaCode only, do not un-hide or change to a numeric literal
+    /*
+     * Framework static final constants that are primitives or Strings
+     * accessed by CTS tests or internal applications must be set from methods
+     * (or in a static block) to prevent Java compile-time replacement.
+     * We set them from methods so they are read from the device framework.
+     * Do not un-hide or change to a numeric literal.
      */
-    public static final int OUT_CHANNEL_COUNT_MAX = native_get_FCC_8();
-    private static native int native_get_FCC_8();
+
+    /** Maximum value for AudioTrack channel count
+     * @hide
+     */
+    public static final int OUT_CHANNEL_COUNT_MAX = native_getMaxChannelCount();
+    private static native int native_getMaxChannelCount();
+
+    /** Maximum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MAX = native_getMaxSampleRate();
+    private static native int native_getMaxSampleRate();
+
+    /** Minimum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MIN = native_getMinSampleRate();
+    private static native int native_getMinSampleRate();
 
     // Expose only the getter method publicly so we can change it in the future
     private static final int NUM_STREAM_TYPES = 12;
diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java
index d155576..184b359 100644
--- a/media/java/android/media/metrics/PlaybackErrorEvent.java
+++ b/media/java/android/media/metrics/PlaybackErrorEvent.java
@@ -39,71 +39,95 @@
     /** Error code for runtime errors */
     public static final int ERROR_RUNTIME = 2;
 
-    /** No network */
-    public static final int ERROR_NETWORK_OFFLINE = 3;
-    /** Connection opening error */
-    public static final int ERROR_NETWORK_CONNECT = 4;
-    /** Bad HTTP status code */
-    public static final int ERROR_NETWORK_BAD_STATUS = 5;
-    /** DNS resolution error */
-    public static final int ERROR_NETWORK_DNS = 6;
-    /** Network socket timeout */
-    public static final int ERROR_NETWORK_TIMEOUT = 7;
-    /** Connection closed */
-    public static final int ERROR_NETWORK_CLOSED = 8;
-    /** Other network errors */
-    public static final int ERROR_NETWORK_OTHER = 9;
-
-    /** Manifest parsing error */
-    public static final int ERROR_MEDIA_MANIFEST = 10;
+    /** Error code for lack of network connectivity while trying to access a network resource */
+    public static final int ERROR_IO_NETWORK_UNAVAILABLE = 3;
+    /** Error code for a failure while establishing a network connection */
+    public static final int ERROR_IO_NETWORK_CONNECTION_FAILED = 4;
+    /** Error code for an HTTP server returning an unexpected HTTP response status code */
+    public static final int ERROR_IO_BAD_HTTP_STATUS = 5;
+    /** Error code for failing to resolve a hostname */
+    public static final int ERROR_IO_DNS_FAILED = 6;
     /**
-     * Media bitstream (audio, video, text, metadata) parsing error, either malformed or
-     * unsupported.
+     * Error code for a network timeout, meaning the server is taking too long to fulfill
+     * a request
      */
-    public static final int ERROR_MEDIA_PARSER = 11;
-    /** Other media errors */
-    public static final int ERROR_MEDIA_OTHER = 12;
+    public static final int ERROR_IO_CONNECTION_TIMEOUT = 7;
+    /** Error code for an existing network connection being unexpectedly closed */
+    public static final int ERROR_IO_CONNECTION_CLOSED = 8;
+    /** Error code for other Input/Output errors */
+    public static final int ERROR_IO_OTHER = 9;
 
-    /** Codec initialization failed */
-    public static final int ERROR_DECODER_INIT = 13;
-    /** Decoding failed */
-    public static final int ERROR_DECODER_DECODE = 14;
-    /** Out of memory */
-    public static final int ERROR_DECODER_OOM = 15;
-    /** Other decoder errors */
-    public static final int ERROR_DECODER_OTHER = 16;
+    /** Error code for a parsing error associated to a media manifest */
+    public static final int ERROR_PARSING_MANIFEST_MALFORMED = 10;
+    /** Error code for a parsing error associated to a media container format bitstream */
+    public static final int ERROR_PARSING_CONTAINER_MALFORMED = 11;
+    /** Error code for other media parsing errors */
+    public static final int ERROR_PARSING_OTHER = 12;
 
-    /** AudioTrack initialization failed */
-    public static final int ERROR_AUDIOTRACK_INIT = 17;
-    /** AudioTrack writing failed */
-    public static final int ERROR_AUDIOTRACK_WRITE = 18;
-    /** Other AudioTrack errors */
-    public static final int ERROR_AUDIOTRACK_OTHER = 19;
+    /** Error code for a decoder initialization failure */
+    public static final int ERROR_DECODER_INIT_FAILED = 13;
+    /** Error code for a failure while trying to decode media samples */
+    public static final int ERROR_DECODING_FAILED = 14;
+    /**
+     * Error code for trying to decode content whose format exceeds the capabilities of the device.
+     */
+    public static final int ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES = 15;
+    /** Error code for other decoding errors */
+    public static final int ERROR_DECODING_OTHER = 16;
 
-    /** Exception in remote controller or player */
+    /** Error code for an AudioTrack initialization failure */
+    public static final int ERROR_AUDIO_TRACK_INIT_FAILED = 17;
+    /** Error code for an AudioTrack write operation failure */
+    public static final int ERROR_AUDIO_TRACK_WRITE_FAILED = 18;
+    /** Error code for other AudioTrack errors */
+    public static final int ERROR_AUDIO_TRACK_OTHER = 19;
+
+    /** Error code for an unidentified error in a remote controller or player */
     public static final int ERROR_PLAYER_REMOTE = 20;
-    /** Error when a Live playback falls behind the Live DVR window. */
+    /**
+     * Error code for the loading position falling behind the sliding window of available live
+     * content.
+     */
     public static final int ERROR_PLAYER_BEHIND_LIVE_WINDOW = 21;
-    /** Other player errors */
+    /** Error code for other player errors */
     public static final int ERROR_PLAYER_OTHER = 22;
 
-    /** Scheme unsupported by device */
-    public static final int ERROR_DRM_UNAVAILABLE = 23;
-    /** Provisioning failed */
+    /** Error code for a chosen DRM protection scheme not being supported by the device */
+    public static final int ERROR_DRM_SCHEME_UNSUPPORTED = 23;
+    /** Error code for a failure while provisioning the device */
     public static final int ERROR_DRM_PROVISIONING_FAILED = 24;
-    /** Failed to acquire license */
-    public static final int ERROR_DRM_LICENSE_ERROR = 25;
-    /** Operation prevented by license policy */
-    public static final int ERROR_DRM_DISALLOWED = 26;
-    /** Failure in the DRM system */
+    /** Error code for a failure while trying to obtain a license */
+    public static final int ERROR_DRM_LICENSE_ACQUISITION_FAILED = 25;
+    /** Error code an operation being disallowed by a license policy */
+    public static final int ERROR_DRM_DISALLOWED_OPERATION = 26;
+    /** Error code for an error in the DRM system */
     public static final int ERROR_DRM_SYSTEM_ERROR = 27;
-    /** Incompatible content */
+    /** Error code for attempting to play incompatible DRM-protected content */
     public static final int ERROR_DRM_CONTENT_ERROR = 28;
-    /** Device has been revoked */
-    public static final int ERROR_DRM_REVOKED = 29;
-    /** Other drm errors */
+    /** Error code for the device having revoked DRM privileges */
+    public static final int ERROR_DRM_DEVICE_REVOKED = 29;
+    /** Error code for other DRM errors */
     public static final int ERROR_DRM_OTHER = 30;
 
+    /** Error code for a non-existent file */
+    public static final int ERROR_IO_FILE_NOT_FOUND = 31;
+    /**
+     * Error code for lack of permission to perform an IO operation, for example, lack of permission
+     * to access internet or external storage.
+     */
+    public static final int ERROR_IO_NO_PERMISSION = 32;
+
+    /** Error code for an unsupported feature in a media manifest */
+    public static final int ERROR_PARSING_MANIFEST_UNSUPPORTED = 33;
+    /**
+     * Error code for attempting to extract a file with an unsupported media container format, or an
+     * unsupported media container feature
+     */
+    public static final int ERROR_PARSING_CONTAINER_UNSUPPORTED = 34;
+
+    /** Error code for trying to decode content whose format is not supported */
+    public static final int ERROR_DECODING_FORMAT_UNSUPPORTED = 35;
+
 
     private final @Nullable String mExceptionStack;
     private final int mErrorCode;
@@ -116,34 +140,39 @@
         ERROR_UNKNOWN,
         ERROR_OTHER,
         ERROR_RUNTIME,
-        ERROR_NETWORK_OFFLINE,
-        ERROR_NETWORK_CONNECT,
-        ERROR_NETWORK_BAD_STATUS,
-        ERROR_NETWORK_DNS,
-        ERROR_NETWORK_TIMEOUT,
-        ERROR_NETWORK_CLOSED,
-        ERROR_NETWORK_OTHER,
-        ERROR_MEDIA_MANIFEST,
-        ERROR_MEDIA_PARSER,
-        ERROR_MEDIA_OTHER,
-        ERROR_DECODER_INIT,
-        ERROR_DECODER_DECODE,
-        ERROR_DECODER_OOM,
-        ERROR_DECODER_OTHER,
-        ERROR_AUDIOTRACK_INIT,
-        ERROR_AUDIOTRACK_WRITE,
-        ERROR_AUDIOTRACK_OTHER,
+        ERROR_IO_NETWORK_UNAVAILABLE,
+        ERROR_IO_NETWORK_CONNECTION_FAILED,
+        ERROR_IO_BAD_HTTP_STATUS,
+        ERROR_IO_DNS_FAILED,
+        ERROR_IO_CONNECTION_TIMEOUT,
+        ERROR_IO_CONNECTION_CLOSED,
+        ERROR_IO_OTHER,
+        ERROR_PARSING_MANIFEST_MALFORMED,
+        ERROR_PARSING_CONTAINER_MALFORMED,
+        ERROR_PARSING_OTHER,
+        ERROR_DECODER_INIT_FAILED,
+        ERROR_DECODING_FAILED,
+        ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES,
+        ERROR_DECODING_OTHER,
+        ERROR_AUDIO_TRACK_INIT_FAILED,
+        ERROR_AUDIO_TRACK_WRITE_FAILED,
+        ERROR_AUDIO_TRACK_OTHER,
         ERROR_PLAYER_REMOTE,
         ERROR_PLAYER_BEHIND_LIVE_WINDOW,
         ERROR_PLAYER_OTHER,
-        ERROR_DRM_UNAVAILABLE,
+        ERROR_DRM_SCHEME_UNSUPPORTED,
         ERROR_DRM_PROVISIONING_FAILED,
-        ERROR_DRM_LICENSE_ERROR,
-        ERROR_DRM_DISALLOWED,
+        ERROR_DRM_LICENSE_ACQUISITION_FAILED,
+        ERROR_DRM_DISALLOWED_OPERATION,
         ERROR_DRM_SYSTEM_ERROR,
         ERROR_DRM_CONTENT_ERROR,
-        ERROR_DRM_REVOKED,
+        ERROR_DRM_DEVICE_REVOKED,
         ERROR_DRM_OTHER,
+        ERROR_IO_FILE_NOT_FOUND,
+        ERROR_IO_NO_PERMISSION,
+        ERROR_PARSING_MANIFEST_UNSUPPORTED,
+        ERROR_PARSING_CONTAINER_UNSUPPORTED,
+        ERROR_DECODING_FORMAT_UNSUPPORTED,
     })
     @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
     public @interface ErrorCode {}
diff --git a/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml b/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml
index 0ecf979..017d1fc 100644
--- a/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml
+++ b/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml
@@ -7,7 +7,7 @@
         errorLine1="        android:id=&quot;@android:id/switch_widget&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml"
+            file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml"
             line="49"
             column="9"/>
     </issue>
@@ -15,7 +15,7 @@
     <issue
         id="NewApi"
         message="`@android:style/Widget.Material.CompoundButton.Switch` requires API level 24 (current min is 21)"
-        errorLine1="    &lt;style name=&quot;Settings.MainSwitch&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
+        errorLine1="    &lt;style name=&quot;MainSwitch.Settingslib&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
         errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
@@ -26,7 +26,7 @@
     <issue
         id="NewApi"
         message="`@android:style/Widget.Material.CompoundButton.Switch` requires API level 24 (current min is 21)"
-        errorLine1="    &lt;style name=&quot;Widget.SwitchBar.Switch&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
+        errorLine1="    &lt;style name=&quot;SwitchBar.Switch.Settingslib&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
         errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
@@ -37,7 +37,7 @@
     <issue
         id="NewApi"
         message="`android:trackTint` requires API level 23 (current min is 21)"
-        errorLine1="        &lt;item name=&quot;android:trackTint&quot;>@color/switchbar_switch_track_tint&lt;/item>"
+        errorLine1="        &lt;item name=&quot;android:trackTint&quot;>@color/settingslib_switchbar_switch_track_tint&lt;/item>"
         errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_disabled.xml
similarity index 85%
copy from packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml
copy to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_disabled.xml
index b646f0a..088e82b 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_disabled.xml
@@ -19,8 +19,8 @@
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/state_off_color"/>
-            <corners android:radius="@dimen/switch_bar_radius"/>
+            <solid android:color="@color/settingslib_state_off_color"/>
+            <corners android:radius="@dimen/settingslib_switch_bar_radius"/>
         </shape>
     </item>
 </ripple>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_off.xml
similarity index 85%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_off.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_off.xml
index b646f0a..088e82b 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_off.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_off.xml
@@ -19,8 +19,8 @@
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/state_off_color"/>
-            <corners android:radius="@dimen/switch_bar_radius"/>
+            <solid android:color="@color/settingslib_state_off_color"/>
+            <corners android:radius="@dimen/settingslib_switch_bar_radius"/>
         </shape>
     </item>
 </ripple>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_on.xml
similarity index 85%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_on.xml
index b646f0a..250188b 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_disabled.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_switch_bar_bg_on.xml
@@ -19,8 +19,8 @@
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/state_off_color"/>
-            <corners android:radius="@dimen/switch_bar_radius"/>
+            <solid android:color="@color/settingslib_state_on_color"/>
+            <corners android:radius="@dimen/settingslib_switch_bar_radius"/>
         </shape>
     </item>
 </ripple>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_disabled.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml
similarity index 66%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_disabled.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml
index 9e6cfbd..900400e 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_disabled.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml
@@ -17,16 +17,16 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:top="@dimen/switch_thumb_margin"
-        android:left="@dimen/switch_thumb_margin"
-        android:right="@dimen/switch_thumb_margin"
-        android:bottom="@dimen/switch_thumb_margin">
+        android:top="@dimen/settingslib_switch_thumb_margin"
+        android:left="@dimen/settingslib_switch_thumb_margin"
+        android:right="@dimen/settingslib_switch_thumb_margin"
+        android:bottom="@dimen/settingslib_switch_thumb_margin">
         <shape android:shape="oval">
             <size
-                android:height="@dimen/switch_thumb_size"
-                android:width="@dimen/switch_thumb_size"/>
+                android:height="@dimen/settingslib_switch_thumb_size"
+                android:width="@dimen/settingslib_switch_thumb_size"/>
             <solid
-                android:color="@color/state_off_color"
+                android:color="@color/settingslib_state_off_color"
                 android:alpha="?android:attr/disabledAlpha"/>
         </shape>
     </item>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml
similarity index 64%
copy from packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
copy to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml
index f6d8815..e54c332 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml
@@ -17,15 +17,15 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:top="@dimen/switch_thumb_margin"
-        android:left="@dimen/switch_thumb_margin"
-        android:right="@dimen/switch_thumb_margin"
-        android:bottom="@dimen/switch_thumb_margin">
+        android:top="@dimen/settingslib_switch_thumb_margin"
+        android:left="@dimen/settingslib_switch_thumb_margin"
+        android:right="@dimen/settingslib_switch_thumb_margin"
+        android:bottom="@dimen/settingslib_switch_thumb_margin">
         <shape android:shape="oval">
             <size
-                android:height="@dimen/switch_thumb_size"
-                android:width="@dimen/switch_thumb_size"/>
-            <solid android:color="@color/state_off_color"/>
+                android:height="@dimen/settingslib_switch_thumb_size"
+                android:width="@dimen/settingslib_switch_thumb_size"/>
+            <solid android:color="@color/settingslib_state_off_color"/>
         </shape>
     </item>
 </layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml
similarity index 64%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml
index f6d8815..0f27fc2 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml
@@ -17,15 +17,15 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:top="@dimen/switch_thumb_margin"
-        android:left="@dimen/switch_thumb_margin"
-        android:right="@dimen/switch_thumb_margin"
-        android:bottom="@dimen/switch_thumb_margin">
+        android:top="@dimen/settingslib_switch_thumb_margin"
+        android:left="@dimen/settingslib_switch_thumb_margin"
+        android:right="@dimen/settingslib_switch_thumb_margin"
+        android:bottom="@dimen/settingslib_switch_thumb_margin">
         <shape android:shape="oval">
             <size
-                android:height="@dimen/switch_thumb_size"
-                android:width="@dimen/switch_thumb_size"/>
-            <solid android:color="@color/state_off_color"/>
+                android:height="@dimen/settingslib_switch_thumb_size"
+                android:width="@dimen/settingslib_switch_thumb_size"/>
+            <solid android:color="@color/settingslib_state_on_color"/>
         </shape>
     </item>
 </layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml
similarity index 72%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml
index a541eaa..06bb779 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml
@@ -16,7 +16,7 @@
   -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/thumb_on" android:state_checked="true"/>
-    <item android:drawable="@drawable/thumb_off" android:state_checked="false"/>
-    <item android:drawable="@drawable/thumb_disabled" android:state_enabled="false"/>
+    <item android:drawable="@drawable/settingslib_thumb_on" android:state_checked="true"/>
+    <item android:drawable="@drawable/settingslib_thumb_off" android:state_checked="false"/>
+    <item android:drawable="@drawable/settingslib_thumb_disabled" android:state_enabled="false"/>
 </selector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_disabled_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_disabled_background.xml
similarity index 76%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/track_disabled_background.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_disabled_background.xml
index b6c7313..15dfcb7 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_disabled_background.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_disabled_background.xml
@@ -17,10 +17,10 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle"
-    android:width="@dimen/switch_track_width"
-    android:height="@dimen/switch_track_height">
+    android:width="@dimen/settingslib_switch_track_width"
+    android:height="@dimen/settingslib_switch_track_height">
     <solid
-        android:color="@color/track_off_color"
+        android:color="@color/settingslib_track_off_color"
         android:alpha="?android:attr/disabledAlpha"/>
-    <corners android:radius="@dimen/switch_track_radius"/>
+    <corners android:radius="@dimen/settingslib_switch_track_radius"/>
 </shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_off_background.xml
similarity index 74%
copy from packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
copy to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_off_background.xml
index f2c11b6..4d79a6e 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_off_background.xml
@@ -17,8 +17,8 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle"
-    android:width="@dimen/switch_track_width"
-    android:height="@dimen/switch_track_height">
-    <solid android:color="@color/track_off_color"/>
-    <corners android:radius="@dimen/switch_track_radius"/>
+    android:width="@dimen/settingslib_switch_track_width"
+    android:height="@dimen/settingslib_switch_track_height">
+    <solid android:color="@color/settingslib_track_off_color"/>
+    <corners android:radius="@dimen/settingslib_switch_track_radius"/>
 </shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_on_background.xml
similarity index 74%
rename from packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
rename to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_on_background.xml
index f2c11b6..c12d012 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_on_background.xml
@@ -17,8 +17,8 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle"
-    android:width="@dimen/switch_track_width"
-    android:height="@dimen/switch_track_height">
-    <solid android:color="@color/track_off_color"/>
-    <corners android:radius="@dimen/switch_track_radius"/>
+    android:width="@dimen/settingslib_switch_track_width"
+    android:height="@dimen/settingslib_switch_track_height">
+    <solid android:color="@color/settingslib_track_on_color"/>
+    <corners android:radius="@dimen/settingslib_switch_track_radius"/>
 </shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml
similarity index 69%
copy from packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
copy to packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml
index a541eaa..a38c3b4 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_selector.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml
@@ -16,7 +16,7 @@
   -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/thumb_on" android:state_checked="true"/>
-    <item android:drawable="@drawable/thumb_off" android:state_checked="false"/>
-    <item android:drawable="@drawable/thumb_disabled" android:state_enabled="false"/>
+    <item android:drawable="@drawable/settingslib_track_on_background" android:state_checked="true"/>
+    <item android:drawable="@drawable/settingslib_track_off_background" android:state_checked="false"/>
+    <item android:drawable="@drawable/settingslib_track_disabled_background" android:state_enabled="false"/>
 </selector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_on.xml
deleted file mode 100644
index afea8bd..0000000
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/switch_bar_bg_on.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2021 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight">
-    <item>
-        <shape android:shape="rectangle">
-            <solid android:color="@color/state_on_color"/>
-            <corners android:radius="@dimen/switch_bar_radius"/>
-        </shape>
-    </item>
-</ripple>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
deleted file mode 100644
index 61230b5..0000000
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:top="@dimen/switch_thumb_margin"
-        android:left="@dimen/switch_thumb_margin"
-        android:right="@dimen/switch_thumb_margin"
-        android:bottom="@dimen/switch_thumb_margin">
-        <shape android:shape="oval">
-            <size
-                android:height="@dimen/switch_thumb_size"
-                android:width="@dimen/switch_thumb_size"/>
-            <solid android:color="@color/state_on_color"/>
-        </shape>
-    </item>
-</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
deleted file mode 100644
index 9246462..0000000
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle"
-    android:width="@dimen/switch_track_width"
-    android:height="@dimen/switch_track_height">
-    <solid android:color="@color/track_on_color"/>
-    <corners android:radius="@dimen/switch_track_radius"/>
-</shape>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml
deleted file mode 100644
index 50a03b9..0000000
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_selector.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/track_on_background" android:state_checked="true"/>
-    <item android:drawable="@drawable/track_off_background" android:state_checked="false"/>
-    <item android:drawable="@drawable/track_disabled_background" android:state_enabled="false"/>
-</selector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
similarity index 76%
rename from packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml
rename to packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index 9ccf63a..27c30ca6 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -28,11 +28,11 @@
 
     <LinearLayout
         android:id="@+id/frame"
-        android:minHeight="@dimen/min_switch_bar_height"
+        android:minHeight="@dimen/settingslib_min_switch_bar_height"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
-        android:paddingLeft="@dimen/switchbar_margin_start"
-        android:paddingRight="@dimen/switchbar_margin_end">
+        android:paddingLeft="@dimen/settingslib_switchbar_margin_start"
+        android:paddingRight="@dimen/settingslib_switchbar_margin_end">
 
         <TextView
             android:id="@+id/switch_text"
@@ -44,16 +44,16 @@
             android:maxLines="2"
             android:ellipsize="end"
             android:textAppearance="?android:attr/textAppearanceListItem"
-            style="@style/MainSwitchText" />
+            style="@style/MainSwitchText.Settingslib" />
 
         <ImageView
             android:id="@+id/restricted_icon"
-            android:layout_width="@dimen/restricted_icon_size"
-            android:layout_height="@dimen/restricted_icon_size"
+            android:layout_width="@dimen/settingslib_restricted_icon_size"
+            android:layout_height="@dimen/settingslib_restricted_icon_size"
             android:tint="?android:attr/colorAccent"
             android:theme="@android:style/Theme.Material"
             android:layout_gravity="center_vertical"
-            android:layout_marginEnd="@dimen/restricted_icon_margin_end"
+            android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
             android:src="@*android:drawable/ic_info"
             android:visibility="gone" />
 
@@ -62,9 +62,9 @@
             android:layout_width="wrap_content"
             android:layout_height="48dp"
             android:layout_gravity="center_vertical"
-            android:track="@drawable/track_selector"
-            android:thumb="@drawable/thumb_selector"
-            android:theme="@style/Settings.MainSwitch"/>
+            android:track="@drawable/settingslib_track_selector"
+            android:thumb="@drawable/settingslib_thumb_selector"
+            android:theme="@style/MainSwitch.Settingslib"/>
     </LinearLayout>
 
 </LinearLayout>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
similarity index 79%
rename from packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
rename to packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
index ac82733..306145a 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
@@ -31,17 +31,17 @@
         android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"
         android:textSize="16sp"
         android:textColor="?android:attr/textColorPrimaryInverse"
-        android:layout_marginStart="@dimen/switchbar_subsettings_margin_start"
+        android:layout_marginStart="@dimen/settingslib_switchbar_subsettings_margin_start"
         android:textAlignment="viewStart"/>
 
     <ImageView
         android:id="@+id/restricted_icon"
-        android:layout_width="@dimen/restricted_icon_size"
-        android:layout_height="@dimen/restricted_icon_size"
+        android:layout_width="@dimen/settingslib_restricted_icon_size"
+        android:layout_height="@dimen/settingslib_restricted_icon_size"
         android:tint="?android:attr/colorAccent"
         android:theme="@android:style/Theme.Material"
         android:layout_gravity="center_vertical"
-        android:layout_marginEnd="@dimen/restricted_icon_margin_end"
+        android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
         android:src="@*android:drawable/ic_info"
         android:visibility="gone"/>
 
@@ -50,7 +50,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        android:layout_marginEnd="@dimen/switchbar_subsettings_margin_end"
-        android:theme="@style/Widget.SwitchBar.Switch"/>
+        android:layout_marginEnd="@dimen/settingslib_switchbar_subsettings_margin_end"
+        android:theme="@style/SwitchBar.Switch.Settingslib"/>
 </LinearLayout>
 
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
similarity index 94%
rename from packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml
rename to packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
index efc047c..eccf0c0 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_layout.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml
@@ -20,7 +20,7 @@
     android:layout_width="match_parent" >
 
     <com.android.settingslib.widget.MainSwitchBar
-        android:id="@+id/main_switch_bar"
+        android:id="@+id/settingslib_main_switch_bar"
         android:visibility="gone"
         android:layout_height="wrap_content"
         android:layout_width="match_parent" />
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
index 7457285..c8d06d4 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
@@ -16,9 +16,9 @@
   -->
 
 <resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <color name="switchbar_switch_track_tint">#82000000</color>
-    <color name="switchbar_switch_thumb_tint">@android:color/black</color>
+    <color name="settingslib_switchbar_switch_track_tint">#82000000</color>
+    <color name="settingslib_switchbar_switch_thumb_tint">@android:color/black</color>
 
     <!-- Material next track on color-->
-    <color name="track_on_color">?androidprv:attr/colorSurfaceHighlight</color>
+    <color name="settingslib_track_on_color">?androidprv:attr/colorSurfaceHighlight</color>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml
index c6bb77d..55a2589 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml
@@ -18,5 +18,5 @@
 <resources>
 
     <!-- SwitchBar sub settings margin start / end -->
-    <dimen name="switchbar_subsettings_margin_start">80dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_start">80dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml
index 3e941c2..53995bc 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml
@@ -18,6 +18,6 @@
 <resources>
 
     <!-- SwitchBar sub settings margin start / end -->
-    <dimen name="switchbar_subsettings_margin_start">128dp</dimen>
-    <dimen name="switchbar_subsettings_margin_end">128dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_start">128dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_end">128dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml
index 2f040da..9015c58 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml
@@ -18,6 +18,6 @@
 <resources>
 
     <!-- SwitchBar sub settings margin start / end -->
-    <dimen name="switchbar_subsettings_margin_start">80dp</dimen>
-    <dimen name="switchbar_subsettings_margin_end">80dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_start">80dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_end">80dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
index ea7bfd4..3fcc1dd 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
@@ -16,19 +16,19 @@
   -->
 
 <resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <color name="switchbar_background_color">@*android:color/material_grey_600</color>
-    <color name="switchbar_switch_track_tint">#BFFFFFFF</color>
-    <color name="switchbar_switch_thumb_tint">@android:color/white</color>
+    <color name="settingslib_switchbar_background_color">@*android:color/material_grey_600</color>
+    <color name="settingslib_switchbar_switch_track_tint">#BFFFFFFF</color>
+    <color name="settingslib_switchbar_switch_thumb_tint">@android:color/white</color>
 
     <!-- Material next state on color-->
-    <color name="state_on_color">?androidprv:attr/colorAccentPrimary</color>
+    <color name="settingslib_state_on_color">?androidprv:attr/colorAccentPrimary</color>
 
     <!-- Material next state off color-->
-    <color name="state_off_color">?androidprv:attr/colorAccentSecondary</color>
+    <color name="settingslib_state_off_color">?androidprv:attr/colorAccentSecondary</color>
 
     <!-- Material next track on color-->
-    <color name="track_on_color">?androidprv:attr/colorAccentPrimaryVariant</color>
+    <color name="settingslib_track_on_color">?androidprv:attr/colorAccentPrimaryVariant</color>
 
     <!-- Material next track off color-->
-    <color name="track_off_color">?androidprv:attr/colorAccentSecondaryVariant</color>
+    <color name="settingslib_track_off_color">?androidprv:attr/colorAccentSecondaryVariant</color>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
index 67886bc..4c528da 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -18,42 +18,42 @@
 <resources>
 
     <!-- Size of layout margin left -->
-    <dimen name="switchbar_margin_start">24dp</dimen>
+    <dimen name="settingslib_switchbar_margin_start">24dp</dimen>
 
     <!-- Size of layout margin right -->
-    <dimen name="switchbar_margin_end">16dp</dimen>
+    <dimen name="settingslib_switchbar_margin_end">16dp</dimen>
 
     <!-- Minimum width of switch -->
-    <dimen name="min_switch_width">52dp</dimen>
+    <dimen name="settingslib_min_switch_width">52dp</dimen>
 
     <!-- Minimum width of switch bar -->
-    <dimen name="min_switch_bar_height">72dp</dimen>
+    <dimen name="settingslib_min_switch_bar_height">72dp</dimen>
 
     <!-- Restricted icon size in switch bar -->
-    <dimen name="restricted_icon_size">@*android:dimen/config_restrictedIconSize</dimen>
+    <dimen name="settingslib_restricted_icon_size">@*android:dimen/config_restrictedIconSize</dimen>
 
     <!-- Restricted icon in switch bar -->
-    <dimen name="restricted_icon_margin_end">16dp</dimen>
+    <dimen name="settingslib_restricted_icon_margin_end">16dp</dimen>
 
     <!-- Radius of switch bar -->
-    <dimen name="switch_bar_radius">28dp</dimen>
+    <dimen name="settingslib_switch_bar_radius">28dp</dimen>
 
     <!-- Margin of switch thumb -->
-    <dimen name="switch_thumb_margin">4dp</dimen>
+    <dimen name="settingslib_switch_thumb_margin">4dp</dimen>
 
     <!-- Size of switch thumb -->
-    <dimen name="switch_thumb_size">20dp</dimen>
+    <dimen name="settingslib_switch_thumb_size">20dp</dimen>
 
     <!-- Width of switch track -->
-    <dimen name="switch_track_width">52dp</dimen>
+    <dimen name="settingslib_switch_track_width">52dp</dimen>
 
     <!-- Height of switch track -->
-    <dimen name="switch_track_height">28dp</dimen>
+    <dimen name="settingslib_switch_track_height">28dp</dimen>
 
     <!-- Radius of switch track -->
-    <dimen name="switch_track_radius">35dp</dimen>
+    <dimen name="settingslib_switch_track_radius">35dp</dimen>
 
     <!-- SwitchBar sub settings margin start / end -->
-    <dimen name="switchbar_subsettings_margin_start">72dp</dimen>
-    <dimen name="switchbar_subsettings_margin_end">16dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_start">72dp</dimen>
+    <dimen name="settingslib_switchbar_subsettings_margin_end">16dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
index 5867695..472025a 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
@@ -17,19 +17,19 @@
 
 <resources>
 
-    <style name="MainSwitchText">
+    <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
         <item name="android:textSize">20sp</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:textColor">@android:color/black</item>
     </style>
 
-    <style name="Settings.MainSwitch" parent="@android:style/Widget.Material.CompoundButton.Switch">
-        <item name="android:switchMinWidth">@dimen/min_switch_width</item>
+    <style name="MainSwitch.Settingslib" parent="@android:style/Widget.Material.CompoundButton.Switch">
+        <item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
     </style>
 
-    <style name="Widget.SwitchBar.Switch" parent="@android:style/Widget.Material.CompoundButton.Switch">
-        <item name="android:trackTint">@color/switchbar_switch_track_tint</item>
-        <item name="android:thumbTint">@color/switchbar_switch_thumb_tint</item>
+    <style name="SwitchBar.Switch.Settingslib" parent="@android:style/Widget.Material.CompoundButton.Switch">
+        <item name="android:trackTint">@color/settingslib_switchbar_switch_track_tint</item>
+        <item name="android:thumbTint">@color/settingslib_switchbar_switch_thumb_tint</item>
         <item name="android:minHeight">48dp</item>
         <item name="android:minWidth">48dp</item>
     </style>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 7913e0a..0748acd 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -72,14 +72,15 @@
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        LayoutInflater.from(context).inflate(resourceId(context, "layout", "main_switch_bar"),
+        LayoutInflater.from(context).inflate(
+                resourceId(context, "layout", "settingslib_main_switch_bar"),
                 this);
 
         if (!BuildCompat.isAtLeastS()) {
             final TypedArray a = context.obtainStyledAttributes(
                     new int[]{android.R.attr.colorAccent});
             mBackgroundActivatedColor = a.getColor(0, 0);
-            mBackgroundColor = context.getColor(R.color.switchbar_background_color);
+            mBackgroundColor = context.getColor(R.color.settingslib_switchbar_background_color);
             a.recycle();
         }
 
@@ -89,9 +90,12 @@
         mFrameView = findViewById(R.id.frame);
         mTextView = (TextView) findViewById(R.id.switch_text);
         mSwitch = (Switch) findViewById(android.R.id.switch_widget);
-        mBackgroundOn = getContext().getDrawable(R.drawable.switch_bar_bg_on);
-        mBackgroundOff = getContext().getDrawable(R.drawable.switch_bar_bg_off);
-        mBackgroundDisabled = getContext().getDrawable(R.drawable.switch_bar_bg_disabled);
+        mBackgroundOn = getContext().getDrawable(
+                resourceId(context, "drawable", "settingslib_switch_bar_bg_on"));
+        mBackgroundOff = getContext().getDrawable(
+                resourceId(context, "drawable", "settingslib_switch_bar_bg_off"));
+        mBackgroundDisabled = getContext().getDrawable(
+                resourceId(context, "drawable", "settingslib_switch_bar_bg_disabled"));
 
         addOnSwitchChangeListener((switchView, isChecked) -> setChecked(isChecked));
 
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index cafc703..6f371ce 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -66,13 +66,13 @@
         holder.setDividerAllowedAbove(false);
         holder.setDividerAllowedBelow(false);
 
-        mMainSwitchBar = (MainSwitchBar) holder.findViewById(R.id.main_switch_bar);
+        mMainSwitchBar = (MainSwitchBar) holder.findViewById(R.id.settingslib_main_switch_bar);
         updateStatus(isChecked());
         registerListenerToSwitchBar();
     }
 
     private void init(Context context, AttributeSet attrs) {
-        setLayoutResource(R.layout.main_switch_layout);
+        setLayoutResource(R.layout.settingslib_main_switch_layout);
 
         if (attrs != null) {
             final TypedArray a = context.obtainStyledAttributes(attrs,
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 70b826a..08d87df 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1422,7 +1422,7 @@
     <string name="user_set_lock_button">Set lock</string>
     <!-- Label for switching to other user in the user switcher [CHAR LIMIT=35] -->
     <string name="user_switch_to_user">Switch to <xliff:g id="user_name" example="John Doe">%s</xliff:g></string>
-    <!-- Dialog message when creating a new user [CHAR LIMIT=40] -->
+    <!-- Dialog message when creating a new user [CHAR LIMIT=NONE] -->
     <string name="creating_new_user_dialog_message">Creating new user…</string>
     <!-- Text shown to notify that the creation of new user has failed. [CHAR LIMIT=40] -->
     <string name="add_user_failed">Failed to create a new user</string>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
index 12f329d..e58c04a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
@@ -41,7 +41,8 @@
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mRootView = View.inflate(mContext, R.layout.main_switch_layout, null /* parent */);
+        mRootView = View.inflate(mContext, R.layout.settingslib_main_switch_layout,
+                null /* parent */);
         mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
         mPreference = new MainSwitchPreference(mContext);
     }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 7cd7c9e..74aa138 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.shared.pip;
 
-import static android.graphics.Matrix.MSCALE_X;
-import static android.graphics.Matrix.MSCALE_Y;
-
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -32,15 +29,17 @@
  * source of truth on enabling/disabling and the actual value of corner radius.
  */
 public class PipSurfaceTransactionHelper {
-    /** corner radius is currently disabled. */
-    private final float mCornerRadius = 0f;
-
+    private final int mCornerRadius;
     private final Matrix mTmpTransform = new Matrix();
     private final float[] mTmpFloat9 = new float[9];
     private final RectF mTmpSourceRectF = new RectF();
     private final RectF mTmpDestinationRectF = new RectF();
     private final Rect mTmpDestinationRect = new Rect();
 
+    public PipSurfaceTransactionHelper(int cornerRadius) {
+        mCornerRadius = cornerRadius;
+    }
+
     public PictureInPictureSurfaceTransaction scale(
             SurfaceControl.Transaction tx, SurfaceControl leash,
             Rect sourceBounds, Rect destinationBounds) {
@@ -52,8 +51,7 @@
                 .setCornerRadius(leash, mCornerRadius);
         return new PictureInPictureSurfaceTransaction(
                 mTmpDestinationRectF.left, mTmpDestinationRectF.top,
-                mTmpFloat9[MSCALE_X], mTmpFloat9[MSCALE_Y],
-                0 /* rotation*/, mCornerRadius, sourceBounds);
+                mTmpFloat9, 0 /* rotation */, mCornerRadius, sourceBounds);
     }
 
     public PictureInPictureSurfaceTransaction scale(
@@ -68,9 +66,7 @@
                 .setPosition(leash, positionX, positionY)
                 .setCornerRadius(leash, mCornerRadius);
         return new PictureInPictureSurfaceTransaction(
-                positionX, positionY,
-                mTmpFloat9[MSCALE_X], mTmpFloat9[MSCALE_Y],
-                degree, mCornerRadius, sourceBounds);
+                positionX, positionY, mTmpFloat9, degree, mCornerRadius, sourceBounds);
     }
 
     public PictureInPictureSurfaceTransaction scaleAndCrop(
@@ -92,7 +88,7 @@
                 .setPosition(leash, left, top)
                 .setCornerRadius(leash, mCornerRadius);
         return new PictureInPictureSurfaceTransaction(
-                left, top, scale, scale, 0 /* rotation */, mCornerRadius, mTmpDestinationRect);
+                left, top, mTmpFloat9, 0 /* rotation */, mCornerRadius, mTmpDestinationRect);
     }
 
     public PictureInPictureSurfaceTransaction scaleAndRotate(
@@ -114,7 +110,7 @@
                 .setPosition(leash, positionX, positionY)
                 .setCornerRadius(leash, mCornerRadius);
         return new PictureInPictureSurfaceTransaction(
-                positionX, positionY, scale, scale, degree, mCornerRadius, mTmpDestinationRect);
+                positionX, positionY, mTmpFloat9, degree, mCornerRadius, mTmpDestinationRect);
     }
 
     /** @return {@link SurfaceControl.Transaction} instance with vsync-id */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 48f9a58..36a0acc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -104,6 +104,7 @@
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -229,6 +230,7 @@
     private AlarmManager mAlarmManager;
     private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
+    private final SysuiStatusBarStateController mStatusBarStateController;
     private final Executor mUiBgExecutor;
 
     private boolean mSystemReady;
@@ -779,7 +781,7 @@
             NavigationModeController navigationModeController,
             KeyguardDisplayManager keyguardDisplayManager,
             DozeParameters dozeParameters,
-            StatusBarStateController statusBarStateController,
+            SysuiStatusBarStateController statusBarStateController,
             KeyguardStateController keyguardStateController,
             Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy) {
         super(context);
@@ -808,6 +810,7 @@
                     mInGestureNavigationMode = QuickStepContract.isGesturalMode(mode);
                 }));
         mDozeParameters = dozeParameters;
+        mStatusBarStateController = statusBarStateController;
         statusBarStateController.addCallback(this);
 
         mKeyguardStateController = keyguardStateController;
@@ -2100,19 +2103,17 @@
                 playSounds(false);
             }
 
-            if (KeyguardService.sEnableRemoteKeyguardAnimation) {
+            // When remaining on the shade, there's no need to do a fancy remote animation,
+            // it will dismiss the panel in that case.
+            if (KeyguardService.sEnableRemoteKeyguardAnimation
+                    && !mStatusBarStateController.leaveOpenOnKeyguardHide()
+                    && apps != null && apps.length > 0) {
                 mSurfaceBehindRemoteAnimationFinishedCallback = finishedCallback;
                 mSurfaceBehindRemoteAnimationRunning = true;
 
-                if (apps != null && apps.length > 0) {
-                    // Pass the surface and metadata to the unlock animation controller.
-                    mKeyguardUnlockAnimationControllerLazy.get().notifyStartKeyguardExitAnimation(
-                            apps[0], startTime, mSurfaceBehindRemoteAnimationRequested);
-                } else {
-                    // We weren't given any surfaces to animate, so just finish.
-                    onKeyguardExitRemoteAnimationFinished();
-                    return;
-                }
+                // Pass the surface and metadata to the unlock animation controller.
+                mKeyguardUnlockAnimationControllerLazy.get().notifyStartKeyguardExitAnimation(
+                        apps[0], startTime, mSurfaceBehindRemoteAnimationRequested);
             } else {
                 setShowingLocked(false);
                 mWakeAndUnlocking = false;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index ecee1b5..119e9c4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -47,6 +47,7 @@
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardLiftController;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -94,7 +95,7 @@
             NavigationModeController navigationModeController,
             KeyguardDisplayManager keyguardDisplayManager,
             DozeParameters dozeParameters,
-            StatusBarStateController statusBarStateController,
+            SysuiStatusBarStateController statusBarStateController,
             KeyguardStateController keyguardStateController,
             Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController) {
         return new KeyguardViewMediator(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 1ff30a3..6baacb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -57,6 +57,7 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.GcUtils;
 import com.android.internal.view.AppearanceRegion;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 import com.android.systemui.statusbar.commandline.CommandRegistry;
@@ -1086,6 +1087,12 @@
         thr.start();
     }
 
+    @Override
+    public void runGcForTest() {
+        // Gc sysui
+        GcUtils.runGcAndFinalizersSync();
+    }
+
     private final class H extends Handler {
         private H(Looper l) {
             super(l);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 26b68af..6c30674 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -280,8 +280,8 @@
 
     @WMSingleton
     @Provides
-    static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper(Context context) {
-        return new PipSurfaceTransactionHelper(context);
+    static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper() {
+        return new PipSurfaceTransactionHelper();
     }
 
     @WMSingleton
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 5c87741..6f03f5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -46,7 +46,7 @@
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -79,7 +79,7 @@
     private @Mock NavigationModeController mNavigationModeController;
     private @Mock KeyguardDisplayManager mKeyguardDisplayManager;
     private @Mock DozeParameters mDozeParameters;
-    private @Mock StatusBarStateController mStatusBarStateController;
+    private @Mock SysuiStatusBarStateController mStatusBarStateController;
     private @Mock KeyguardStateController mKeyguardStateController;
     private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
     private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 794cb93..d574e74 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -49,6 +49,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.system.ErrnoException;
@@ -65,6 +66,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.net.module.util.NetdUtils;
+import com.android.net.module.util.PermissionUtils;
 
 import libcore.io.IoUtils;
 
@@ -466,8 +468,7 @@
 
         /** Safety method; guards against access of other user's UserRecords */
         private void checkCallerUid(int uid) {
-            if (uid != Binder.getCallingUid()
-                    && android.os.Process.SYSTEM_UID != Binder.getCallingUid()) {
+            if (uid != Binder.getCallingUid() && Process.SYSTEM_UID != Binder.getCallingUid()) {
                 throw new SecurityException("Attempted access of unowned resources");
             }
         }
@@ -1105,11 +1106,15 @@
      * Checks the user-provided direction field and throws an IllegalArgumentException if it is not
      * DIRECTION_IN or DIRECTION_OUT
      */
-    private static void checkDirection(int direction) {
+    private void checkDirection(int direction) {
         switch (direction) {
             case IpSecManager.DIRECTION_OUT:
             case IpSecManager.DIRECTION_IN:
                 return;
+            case IpSecManager.DIRECTION_FWD:
+                // Only NETWORK_STACK or PERMISSION_NETWORK_STACK allowed to use forward policies
+                PermissionUtils.enforceNetworkStackPermission(mContext);
+                return;
         }
         throw new IllegalArgumentException("Invalid Direction: " + direction);
     }
@@ -1353,6 +1358,16 @@
                         ikey,
                         0xffffffff,
                         resourceId);
+                netd.ipSecAddSecurityPolicy(
+                        callerUid,
+                        selAddrFamily,
+                        IpSecManager.DIRECTION_FWD,
+                        remoteAddr,
+                        localAddr,
+                        0,
+                        ikey,
+                        0xffffffff,
+                        resourceId);
             }
 
             userRecord.mTunnelInterfaceRecords.put(
@@ -1820,7 +1835,7 @@
         int mark =
                 (direction == IpSecManager.DIRECTION_OUT)
                         ? tunnelInterfaceInfo.getOkey()
-                        : tunnelInterfaceInfo.getIkey();
+                        : tunnelInterfaceInfo.getIkey(); // Ikey also used for FWD policies
 
         try {
             // Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index df4c2cfc..2bb9084 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -432,6 +432,7 @@
             synchronized (mLock) {
                 final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
                 mLastSnapshot = snapshot;
+                Slog.d(TAG, "new snapshot: " + mLastSnapshot);
 
                 // Start any VCN instances as necessary
                 for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
@@ -534,7 +535,7 @@
 
     @GuardedBy("mLock")
     private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
-        Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
 
         // TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active
         //                    VCN.
@@ -556,7 +557,7 @@
     @GuardedBy("mLock")
     private void startOrUpdateVcnLocked(
             @NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
-        Slog.v(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
 
         if (mVcns.containsKey(subscriptionGroup)) {
             final Vcn vcn = mVcns.get(subscriptionGroup);
@@ -582,7 +583,7 @@
         if (!config.getProvisioningPackageName().equals(opPkgName)) {
             throw new IllegalArgumentException("Mismatched caller and VcnConfig creator");
         }
-        Slog.v(TAG, "VCN config updated for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "VCN config updated for subGrp: " + subscriptionGroup);
 
         mContext.getSystemService(AppOpsManager.class)
                 .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName());
@@ -607,7 +608,7 @@
     public void clearVcnConfig(@NonNull ParcelUuid subscriptionGroup, @NonNull String opPkgName) {
         requireNonNull(subscriptionGroup, "subscriptionGroup was null");
         requireNonNull(opPkgName, "opPkgName was null");
-        Slog.v(TAG, "VCN config cleared for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "VCN config cleared for subGrp: " + subscriptionGroup);
 
         mContext.getSystemService(AppOpsManager.class)
                 .checkPackage(mDeps.getBinderCallingUid(), opPkgName);
@@ -843,8 +844,14 @@
             }
 
             final NetworkCapabilities result = ncBuilder.build();
-            return new VcnUnderlyingNetworkPolicy(
+            final VcnUnderlyingNetworkPolicy policy = new VcnUnderlyingNetworkPolicy(
                     mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
+
+            if (VDBG) {
+                Slog.d(TAG, "getUnderlyingNetworkPolicy() called for caps: " + networkCapabilities
+                        + "; and lp: " + linkProperties + "; result = " + policy);
+            }
+            return policy;
         });
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3a8b547..70538bb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7726,16 +7726,17 @@
             ApplicationErrorReport.CrashInfo crashInfo) {
         float loadingProgress = 1;
         IncrementalMetrics incrementalMetrics = null;
-        // Notify package manager service to possibly update package state
+        // Obtain Incremental information if available
         if (r != null && r.info != null && r.info.packageName != null) {
-            final String codePath = r.info.getCodePath();
             IncrementalStatesInfo incrementalStatesInfo =
                     mPackageManagerInt.getIncrementalStatesInfo(r.info.packageName, r.uid,
                             r.userId);
             if (incrementalStatesInfo != null) {
                 loadingProgress = incrementalStatesInfo.getProgress();
             }
-            if (IncrementalManager.isIncrementalPath(codePath)) {
+            final String codePath = r.info.getCodePath();
+            if (codePath != null && !codePath.isEmpty()
+                    && IncrementalManager.isIncrementalPath(codePath)) {
                 // Report in the main log about the incremental package
                 Slog.e(TAG, "App crashed on incremental package " + r.info.packageName
                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index da06753..1b5483a 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -879,7 +879,7 @@
         if (TextUtils.equals(pkgName, processName)) {
             // Omit the process name here to save space
             processName = null;
-        } else if (processName != null && processName.startsWith(pkgName)) {
+        } else if (processName != null && pkgName != null && processName.startsWith(pkgName)) {
             // Strip the prefix to save space
             processName = processName.substring(pkgName.length());
         }
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index f41c364..1ecb9eb 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -31,6 +31,8 @@
 
 import libcore.io.IoUtils;
 
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
@@ -43,8 +45,12 @@
 public class LmkdConnection {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM;
 
-    // lmkd reply max size in bytes
-    private static final int LMKD_REPLY_MAX_SIZE = 12;
+    /**
+     * Max LMKD reply packet length in bytes
+     * Used to hold the data for the statsd atoms logging
+     * Must be in sync with statslog.h
+     */
+    private static final int LMKD_REPLY_MAX_SIZE = 214;
 
     // connection listener interface
     interface LmkdConnectionListener {
@@ -70,7 +76,7 @@
          * @param receivedLen Size of the data received
          * @return True if the message has been handled correctly, false otherwise.
          */
-        boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen);
+        boolean handleUnsolicitedMessage(DataInputStream inputData, int receivedLen);
     }
 
     private final MessageQueue mMsgQueue;
@@ -95,6 +101,10 @@
     private final ByteBuffer mInputBuf =
             ByteBuffer.allocate(LMKD_REPLY_MAX_SIZE);
 
+    // Input stream to parse the incoming data
+    private final DataInputStream mInputData = new DataInputStream(
+            new ByteArrayInputStream(mInputBuf.array()));
+
     // object to protect mReplyBuf and to wait/notify when reply is received
     private final Object mReplyBufLock = new Object();
 
@@ -186,26 +196,32 @@
     private void processIncomingData() {
         int len = read(mInputBuf);
         if (len > 0) {
-            synchronized (mReplyBufLock) {
-                if (mReplyBuf != null) {
-                    if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
-                        // copy into reply buffer
-                        mReplyBuf.put(mInputBuf.array(), 0, len);
-                        mReplyBuf.rewind();
-                        // wakeup the waiting thread
-                        mReplyBufLock.notifyAll();
-                    } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
-                        // received unexpected packet
-                        // treat this as an error
-                        mReplyBuf = null;
-                        mReplyBufLock.notifyAll();
-                        Slog.e(TAG, "Received an unexpected packet from lmkd");
+            try {
+                // reset InputStream to point into mInputBuf.array() begin
+                mInputData.reset();
+                synchronized (mReplyBufLock) {
+                    if (mReplyBuf != null) {
+                        if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
+                            // copy into reply buffer
+                            mReplyBuf.put(mInputBuf.array(), 0, len);
+                            mReplyBuf.rewind();
+                            // wakeup the waiting thread
+                            mReplyBufLock.notifyAll();
+                        } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
+                            // received unexpected packet
+                            // treat this as an error
+                            mReplyBuf = null;
+                            mReplyBufLock.notifyAll();
+                            Slog.e(TAG, "Received an unexpected packet from lmkd");
+                        }
+                    } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
+                        // received asynchronous communication from lmkd
+                        // but we don't recognize it.
+                        Slog.w(TAG, "Received an unexpected packet from lmkd");
                     }
-                } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
-                    // received asynchronous communication from lmkd
-                    // but we don't recognize it.
-                    Slog.w(TAG, "Received an unexpected packet from lmkd");
                 }
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to parse lmkd data buffer. Size = " + len);
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/LmkdStatsReporter.java b/services/core/java/com/android/server/am/LmkdStatsReporter.java
new file mode 100644
index 0000000..c702d78
--- /dev/null
+++ b/services/core/java/com/android/server/am/LmkdStatsReporter.java
@@ -0,0 +1,107 @@
+/*
+ * 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.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.util.Slog;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * Activity manager communication with lmkd data handling and statsd atom logging
+ */
+public final class LmkdStatsReporter {
+
+    static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdStatsReporter" : TAG_AM;
+
+    public static final int KILL_OCCURRED_MSG_SIZE = 80;
+    public static final int STATE_CHANGED_MSG_SIZE = 8;
+
+    private static final int PRESSURE_AFTER_KILL = 0;
+    private static final int NOT_RESPONDING = 1;
+    private static final int LOW_SWAP_AND_THRASHING = 2;
+    private static final int LOW_MEM_AND_SWAP = 3;
+    private static final int LOW_MEM_AND_THRASHING = 4;
+    private static final int DIRECT_RECL_AND_THRASHING = 5;
+    private static final int LOW_MEM_AND_SWAP_UTIL = 6;
+
+    /**
+     * Processes the LMK_KILL_OCCURRED packet data
+     * Logs the event when LMKD kills a process to reduce memory pressure.
+     * Code: LMK_KILL_OCCURRED = 51
+     */
+    public static void logKillOccurred(DataInputStream inputData) {
+        try {
+            final long pgFault = inputData.readLong();
+            final long pgMajFault = inputData.readLong();
+            final long rssInBytes = inputData.readLong();
+            final long cacheInBytes = inputData.readLong();
+            final long swapInBytes = inputData.readLong();
+            final long processStartTimeNS = inputData.readLong();
+            final int uid = inputData.readInt();
+            final int oomScore = inputData.readInt();
+            final int minOomScore = inputData.readInt();
+            final int freeMemKb = inputData.readInt();
+            final int freeSwapKb = inputData.readInt();
+            final int killReason = inputData.readInt();
+            final String procName = inputData.readUTF();
+
+            FrameworkStatsLog.write(FrameworkStatsLog.LMK_KILL_OCCURRED, uid, procName, oomScore,
+                    pgFault, pgMajFault, rssInBytes, cacheInBytes, swapInBytes, processStartTimeNS,
+                    minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason));
+        } catch (IOException e) {
+            Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
+            return;
+        }
+    }
+
+    /**
+     * Processes the LMK_STATE_CHANGED packet
+     * Logs the change in LMKD state which is used as start/stop boundaries for logging
+     * LMK_KILL_OCCURRED event.
+     * Code: LMK_STATE_CHANGED = 54
+     */
+    public static void logStateChanged(int state) {
+        FrameworkStatsLog.write(FrameworkStatsLog.LMK_STATE_CHANGED, state);
+    }
+
+    private static int mapKillReason(int reason) {
+        switch (reason) {
+            case PRESSURE_AFTER_KILL:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__PRESSURE_AFTER_KILL;
+            case NOT_RESPONDING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__NOT_RESPONDING;
+            case LOW_SWAP_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_SWAP_AND_THRASHING;
+            case LOW_MEM_AND_SWAP:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP;
+            case LOW_MEM_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_THRASHING;
+            case DIRECT_RECL_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_AND_THRASHING;
+            case LOW_MEM_AND_SWAP_UTIL:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL;
+            default:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 5a7e14a..88bd010 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -400,7 +400,8 @@
                 loadingProgress = incrementalStatesInfo.getProgress();
             }
             final String codePath = mApp.info.getCodePath();
-            if (IncrementalManager.isIncrementalPath(codePath)) {
+            if (codePath != null && !codePath.isEmpty()
+                    && IncrementalManager.isIncrementalPath(codePath)) {
                 // Report in the main log that the incremental package is still loading
                 Slog.e(TAG, "App ANR on incremental package " + mApp.info.packageName
                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 8ea50045..0d19209e 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -140,6 +140,7 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -335,18 +336,25 @@
     // LMK_GETKILLCNT
     // LMK_SUBSCRIBE
     // LMK_PROCKILL
+    // LMK_UPDATE_PROPS
+    // LMK_KILL_OCCURRED
+    // LMK_STATE_CHANGED
     static final byte LMK_TARGET = 0;
     static final byte LMK_PROCPRIO = 1;
     static final byte LMK_PROCREMOVE = 2;
     static final byte LMK_PROCPURGE = 3;
     static final byte LMK_GETKILLCNT = 4;
     static final byte LMK_SUBSCRIBE = 5;
-    static final byte LMK_PROCKILL = 6; // Note: this is an unsolicated command
+    static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command
+    static final byte LMK_UPDATE_PROPS = 7;
+    static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event
+    static final byte LMK_STATE_CHANGED = 9; // Msg to subscribed clients on state changed
 
     // Low Memory Killer Daemon command codes.
     // These must be kept in sync with async_event_type definitions in lmkd.h
     //
     static final int LMK_ASYNC_EVENT_KILL = 0;
+    static final int LMK_ASYNC_EVENT_STAT = 1;
 
     // lmkd reconnect delay in msecs
     private static final long LMKD_RECONNECT_DELAY_MS = 1000;
@@ -829,22 +837,44 @@
                         }
 
                         @Override
-                        public boolean handleUnsolicitedMessage(ByteBuffer dataReceived,
+                        public boolean handleUnsolicitedMessage(DataInputStream inputData,
                                 int receivedLen) {
                             if (receivedLen < 4) {
                                 return false;
                             }
-                            switch (dataReceived.getInt(0)) {
-                                case LMK_PROCKILL:
-                                    if (receivedLen != 12) {
+
+                            try {
+                                switch (inputData.readInt()) {
+                                    case LMK_PROCKILL:
+                                        if (receivedLen != 12) {
+                                            return false;
+                                        }
+                                        final int pid = inputData.readInt();
+                                        final int uid = inputData.readInt();
+                                        mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
+                                        return true;
+                                    case LMK_KILL_OCCURRED:
+                                        if (receivedLen
+                                                < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
+                                            return false;
+                                        }
+                                        LmkdStatsReporter.logKillOccurred(inputData);
+                                        return true;
+                                    case LMK_STATE_CHANGED:
+                                        if (receivedLen
+                                                != LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
+                                            return false;
+                                        }
+                                        final int state = inputData.readInt();
+                                        LmkdStatsReporter.logStateChanged(state);
+                                        return true;
+                                    default:
                                         return false;
-                                    }
-                                    mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
-                                            dataReceived.getInt(4), dataReceived.getInt(8));
-                                    return true;
-                                default:
-                                    return false;
+                                }
+                            } catch (IOException e) {
+                                Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
                             }
+                            return false;
                         }
                     }
             );
@@ -1476,6 +1506,12 @@
             buf.putInt(LMK_SUBSCRIBE);
             buf.putInt(LMK_ASYNC_EVENT_KILL);
             ostream.write(buf.array(), 0, buf.position());
+
+            // Subscribe for stats event notifications
+            buf = ByteBuffer.allocate(4 * 2);
+            buf.putInt(LMK_SUBSCRIBE);
+            buf.putInt(LMK_ASYNC_EVENT_STAT);
+            ostream.write(buf.array(), 0, buf.position());
         } catch (IOException ex) {
             return false;
         }
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index f212698..40ab108 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -19,6 +19,8 @@
 import static com.android.server.wm.utils.RotationAnimationUtils.hasProtectedContent;
 
 import android.content.Context;
+import android.graphics.BLASTBufferQueue;
+import android.graphics.PixelFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
@@ -91,6 +93,7 @@
     private int mDisplayHeight;     // real height, not rotated
     private SurfaceControl mSurfaceControl;
     private Surface mSurface;
+    private BLASTBufferQueue mBLASTBufferQueue;
     private NaturalSurfaceLayout mSurfaceLayout;
     private EGLDisplay mEglDisplay;
     private EGLConfig mEglConfig;
@@ -165,21 +168,30 @@
                     "Failed to take screenshot because internal display is disconnected");
             return false;
         }
-        boolean isWideColor = SurfaceControl.getDynamicDisplayInfo(token).activeColorMode
+        final boolean isWideColor = SurfaceControl.getDynamicDisplayInfo(token).activeColorMode
                 == Display.COLOR_MODE_DISPLAY_P3;
 
         // Set mPrepared here so if initialization fails, resources can be cleaned up.
         mPrepared = true;
 
-        SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen();
+        final SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen();
         if (hardwareBuffer == null) {
             dismiss();
             return false;
         }
 
-        boolean isProtected = hasProtectedContent(hardwareBuffer.getHardwareBuffer());
-        if (!(createSurfaceControl(hardwareBuffer.containsSecureLayers())
-                && createEglContext(isProtected) && createEglSurface(isProtected, isWideColor)
+        final boolean isProtected = hasProtectedContent(hardwareBuffer.getHardwareBuffer());
+        if (!createSurfaceControl(hardwareBuffer.containsSecureLayers())) {
+            dismiss();
+            return false;
+        }
+
+        // MODE_FADE use ColorLayer to implement.
+        if (mMode == MODE_FADE) {
+            return true;
+        }
+
+        if (!(createEglContext(isProtected) && createEglSurface(isProtected, isWideColor)
                 && setScreenshotTextureAndSetViewport(hardwareBuffer))) {
             dismiss();
             return false;
@@ -190,7 +202,7 @@
             return false;
         }
         try {
-            if(!initGLShaders(context) || !initGLBuffers() || checkGlErrors("prepare")) {
+            if (!initGLShaders(context) || !initGLBuffers() || checkGlErrors("prepare")) {
                 detachEglContext();
                 dismiss();
                 return false;
@@ -564,7 +576,7 @@
             if (mMode == MODE_FADE) {
                 builder.setColorLayer();
             } else {
-                builder.setBufferSize(mDisplayWidth, mDisplayHeight);
+                builder.setBLASTLayer();
             }
             mSurfaceControl = builder.build();
         } catch (OutOfResourcesException ex) {
@@ -579,9 +591,11 @@
         mSurfaceLayout.onDisplayTransaction(mTransaction);
         mTransaction.apply();
 
-        mSurface = new Surface();
-        mSurface.copyFrom(mSurfaceControl);
-
+        if (mMode != MODE_FADE) {
+            mBLASTBufferQueue = new BLASTBufferQueue("ColorFade", mSurfaceControl,
+                    mDisplayWidth, mDisplayHeight, PixelFormat.TRANSLUCENT);
+            mSurface = mBLASTBufferQueue.createSurface();
+        }
         return true;
     }
 
@@ -707,7 +721,12 @@
             mSurfaceLayout.dispose();
             mSurfaceLayout = null;
             mTransaction.remove(mSurfaceControl).apply();
-            mSurface.release();
+            if (mSurface != null) {
+                mSurface.release();
+                mBLASTBufferQueue.destroy();
+                mSurface = null;
+                mBLASTBufferQueue = null;
+            }
             mSurfaceControl = null;
             mSurfaceVisible = false;
             mSurfaceAlpha = 0f;
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 7c013e0..609bd8b 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Typeface;
+import android.graphics.fonts.Font;
 import android.graphics.fonts.FontFamily;
 import android.graphics.fonts.FontFileUtil;
 import android.graphics.fonts.FontManager;
@@ -194,6 +195,13 @@
             }
         }
 
+        @Override
+        public void tryToCreateTypeface(File file) throws IOException {
+            Font font = new Font.Builder(file).build();
+            FontFamily family = new FontFamily.Builder(font).build();
+            new Typeface.CustomFallbackBuilder(family).build();
+        }
+
         private static ByteBuffer mmap(File file) throws IOException {
             try (FileInputStream in = new FileInputStream(file)) {
                 FileChannel fileChannel = in.getChannel();
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 d532605..e74dac5 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -68,6 +68,8 @@
         String buildFontFileName(File file) throws IOException;
 
         long getRevision(File file) throws IOException;
+
+        void tryToCreateTypeface(File file) throws IOException;
     }
 
     /** Interface to mock fs-verity in tests. */
@@ -372,6 +374,16 @@
                         "Failed to change mode to 711", e);
             }
             FontFileInfo fontFileInfo = validateFontFile(newFontFile);
+
+            // Try to create Typeface and treat as failure something goes wrong.
+            try {
+                mParser.tryToCreateTypeface(fontFileInfo.getFile());
+            } catch (IOException e) {
+                throw new SystemFontException(
+                        FontManager.RESULT_ERROR_INVALID_FONT_FILE,
+                        "Failed to create Typeface from file", e);
+            }
+
             FontConfig fontConfig = getSystemFontConfig();
             if (!addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, false)) {
                 throw new SystemFontException(
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a688868..fc36378 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -12131,6 +12131,8 @@
     public boolean performDexOptMode(String packageName,
             boolean checkProfiles, String targetCompilerFilter, boolean force,
             boolean bootComplete, String splitName) {
+        enforceSystemOrRootOrShell("performDexOptMode");
+
         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
                 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
                 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
diff --git a/services/core/java/com/android/server/policy/GlobalKeyIntent.java b/services/core/java/com/android/server/policy/GlobalKeyIntent.java
new file mode 100644
index 0000000..f8682be
--- /dev/null
+++ b/services/core/java/com/android/server/policy/GlobalKeyIntent.java
@@ -0,0 +1,84 @@
+/*
+ * 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.policy;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.util.Log;
+import android.view.KeyEvent;
+
+/**
+ * This class wrapped the Intent for global key ops.
+ */
+public final class GlobalKeyIntent {
+    private static final String EXTRA_BEGAN_FROM_NON_INTERACTIVE =
+            "EXTRA_BEGAN_FROM_NON_INTERACTIVE";
+
+    private final ComponentName mComponentName;
+    private final KeyEvent mKeyEvent;
+    private final boolean mBeganFromNonInteractive;
+
+    GlobalKeyIntent(@NonNull ComponentName componentName, @NonNull KeyEvent event,
+            boolean beganFromNonInteractive) {
+        mComponentName = componentName;
+        mKeyEvent = new KeyEvent(event);
+        mBeganFromNonInteractive = beganFromNonInteractive;
+    }
+
+    Intent getIntent() {
+        final Intent intent = new Intent(Intent.ACTION_GLOBAL_BUTTON)
+                .setComponent(mComponentName)
+                .setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+                .putExtra(Intent.EXTRA_KEY_EVENT, mKeyEvent)
+                .putExtra(EXTRA_BEGAN_FROM_NON_INTERACTIVE, mBeganFromNonInteractive);
+        return intent;
+    }
+
+    /**
+     * Get the {@link KeyEvent} information of {@link Intent#ACTION_GLOBAL_BUTTON}.
+     */
+    public KeyEvent getKeyEvent() {
+        return mKeyEvent;
+    }
+
+    /**
+     * Indicate if the global key is dispatched from non-interactive mode.
+     * Information of {@link Intent#ACTION_GLOBAL_BUTTON}.
+     */
+    public boolean beganFromNonInteractive() {
+        return mBeganFromNonInteractive;
+    }
+
+    /**
+     * Generate a GlobalKeyIntent from {@link Intent}, the action must be
+     * {@link Intent#ACTION_GLOBAL_BUTTON}.
+     *
+     * @param intent The received intent of the global key.
+     */
+    public static GlobalKeyIntent from(@NonNull Intent intent) {
+        if (intent.getAction() != Intent.ACTION_GLOBAL_BUTTON) {
+            Log.wtf("GlobalKeyIntent", "Intent should be ACTION_GLOBAL_BUTTON");
+            return null;
+        }
+
+        final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+        final boolean fromNonInteractive =
+                intent.getBooleanExtra(EXTRA_BEGAN_FROM_NON_INTERACTIVE, false);
+        return new GlobalKeyIntent(intent.getComponent(), event, fromNonInteractive);
+    }
+}
diff --git a/services/core/java/com/android/server/policy/GlobalKeyManager.java b/services/core/java/com/android/server/policy/GlobalKeyManager.java
index 157f825..2d48452 100644
--- a/services/core/java/com/android/server/policy/GlobalKeyManager.java
+++ b/services/core/java/com/android/server/policy/GlobalKeyManager.java
@@ -39,6 +39,9 @@
  * broadcast to the specified component. The action of the intent will be
  * {@link Intent#ACTION_GLOBAL_BUTTON} and the KeyEvent will be included in the intent with
  * {@link Intent#EXTRA_KEY_EVENT}.
+ *
+ * Use {@link GlobalKeyIntent} to get detail information from received {@link Intent}, includes
+ * {@link KeyEvent} and the information about if the key is dispatched from non-interactive mode.
  */
 final class GlobalKeyManager {
 
@@ -49,13 +52,15 @@
     private static final String TAG_KEY = "key";
     private static final String ATTR_KEY_CODE = "keyCode";
     private static final String ATTR_COMPONENT = "component";
+    private static final String ATTR_DISPATCH_WHEN_NON_INTERACTIVE = "dispatchWhenNonInteractive";
 
     private static final int GLOBAL_KEY_FILE_VERSION = 1;
 
-    private SparseArray<ComponentName> mKeyMapping;
+    private SparseArray<GlobalKeyAction> mKeyMapping;
+    private boolean mBeganFromNonInteractive = false;
 
     public GlobalKeyManager(Context context) {
-        mKeyMapping = new SparseArray<ComponentName>();
+        mKeyMapping = new SparseArray<>();
         loadGlobalKeys(context);
     }
 
@@ -69,13 +74,15 @@
      */
     boolean handleGlobalKey(Context context, int keyCode, KeyEvent event) {
         if (mKeyMapping.size() > 0) {
-            ComponentName component = mKeyMapping.get(keyCode);
-            if (component != null) {
-                Intent intent = new Intent(Intent.ACTION_GLOBAL_BUTTON)
-                        .setComponent(component)
-                        .setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                        .putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(event));
+            GlobalKeyAction action = mKeyMapping.get(keyCode);
+            if (action != null) {
+                final Intent intent = new GlobalKeyIntent(action.mComponentName, event,
+                        mBeganFromNonInteractive).getIntent();
                 context.sendBroadcastAsUser(intent, UserHandle.CURRENT, null);
+
+                if (event.getAction() == KeyEvent.ACTION_UP) {
+                    mBeganFromNonInteractive = false;
+                }
                 return true;
             }
         }
@@ -85,10 +92,35 @@
     /**
      * Returns {@code true} if the key will be handled globally.
      */
-    boolean shouldHandleGlobalKey(int keyCode, KeyEvent event) {
+    boolean shouldHandleGlobalKey(int keyCode) {
         return mKeyMapping.get(keyCode) != null;
     }
 
+    /**
+     * Returns {@code true} if the key will be handled globally.
+     */
+    boolean shouldDispatchFromNonInteractive(int keyCode) {
+        final GlobalKeyAction action = mKeyMapping.get(keyCode);
+        if (action == null) {
+            return false;
+        }
+
+        return action.mDispatchWhenNonInteractive;
+    }
+
+    void setBeganFromNonInteractive() {
+        mBeganFromNonInteractive = true;
+    }
+
+    class GlobalKeyAction {
+        private ComponentName mComponentName;
+        private boolean mDispatchWhenNonInteractive;
+        GlobalKeyAction(String componentName, String dispatchWhenNonInteractive) {
+            mComponentName = ComponentName.unflattenFromString(componentName);
+            mDispatchWhenNonInteractive = Boolean.valueOf(dispatchWhenNonInteractive);
+        }
+    }
+
     private void loadGlobalKeys(Context context) {
         XmlResourceParser parser = null;
         try {
@@ -105,10 +137,12 @@
                     if (TAG_KEY.equals(element)) {
                         String keyCodeName = parser.getAttributeValue(null, ATTR_KEY_CODE);
                         String componentName = parser.getAttributeValue(null, ATTR_COMPONENT);
+                        String dispatchWhenNonInteractive =
+                                parser.getAttributeValue(null, ATTR_DISPATCH_WHEN_NON_INTERACTIVE);
                         int keyCode = KeyEvent.keyCodeFromString(keyCodeName);
                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
-                            mKeyMapping.put(keyCode, ComponentName.unflattenFromString(
-                                    componentName));
+                            mKeyMapping.put(keyCode, new GlobalKeyAction(
+                                    componentName, dispatchWhenNonInteractive));
                         }
                     }
                 }
@@ -138,7 +172,9 @@
             pw.print(prefix);
             pw.print(KeyEvent.keyCodeToString(mKeyMapping.keyAt(i)));
             pw.print("=");
-            pw.println(mKeyMapping.valueAt(i).flattenToString());
+            pw.print(mKeyMapping.valueAt(i).mComponentName.flattenToString());
+            pw.print(",dispatchWhenNonInteractive=");
+            pw.println(mKeyMapping.valueAt(i).mDispatchWhenNonInteractive);
         }
         pw.print(prefix); pw.println("}");
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b56736e..d73203d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3434,7 +3434,16 @@
         // If the key would be handled globally, just return the result, don't worry about special
         // key processing.
         if (isValidGlobalKey(keyCode)
-                && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
+                && mGlobalKeyManager.shouldHandleGlobalKey(keyCode)) {
+            // Dispatch if global key defined dispatchWhenNonInteractive.
+            if (!interactive && isWakeKey && down
+                    && mGlobalKeyManager.shouldDispatchFromNonInteractive(keyCode)) {
+                mGlobalKeyManager.setBeganFromNonInteractive();
+                result = ACTION_PASS_TO_USER;
+                // Since we're dispatching the input, reset the pending key
+                mPendingWakeKey = PENDING_KEY_NULL;
+            }
+
             if (isWakeKey) {
                 wakeUpFromWakeKey(event);
             }
@@ -3988,6 +3997,7 @@
                 Slog.e(TAG, "RemoteException when checking if dreaming", e);
             }
         }
+
         // Otherwise, consume events since the user can't see what is being
         // interacted with.
         return false;
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 12e55e5..ed4a7bf 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -27,6 +27,7 @@
 import static android.ota.nano.OtaPackageMetadata.ApexMetadata;
 
 import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER;
 
 import android.annotation.IntDef;
 import android.apex.CompressedApexInfo;
@@ -398,7 +399,13 @@
 
     @VisibleForTesting
     void onSystemServicesReady() {
-        mInjector.getLockSettingsService().setRebootEscrowListener(this);
+        LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+        if (lockSettings == null) {
+            Slog.e(TAG, "Failed to get lock settings service, skipping set"
+                    + " RebootEscrowListener");
+            return;
+        }
+        lockSettings.setRebootEscrowListener(this);
     }
 
     @Override // Binder call
@@ -564,12 +571,18 @@
             case ROR_NEED_PREPARATION:
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    boolean result = mInjector.getLockSettingsService().prepareRebootEscrow();
-                    // Clear the RoR preparation state if lock settings reports an failure.
-                    if (!result) {
-                        clearRoRPreparationState();
+                    LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+                    if (lockSettings == null) {
+                        Slog.e(TAG, "Failed to get lock settings service, skipping"
+                                + " prepareRebootEscrow");
+                        return false;
                     }
-                    return result;
+                    // Clear the RoR preparation state if lock settings reports an failure.
+                    if (!lockSettings.prepareRebootEscrow()) {
+                        clearRoRPreparationState();
+                        return false;
+                    }
+                    return true;
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -684,7 +697,14 @@
             case ROR_REQUESTED_NEED_CLEAR:
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    return mInjector.getLockSettingsService().clearRebootEscrow();
+                    LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+                    if (lockSettings == null) {
+                        Slog.e(TAG, "Failed to get lock settings service, skipping"
+                                + " clearRebootEscrow");
+                        return false;
+                    }
+
+                    return lockSettings.clearRebootEscrow();
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -778,7 +798,15 @@
         final long origId = Binder.clearCallingIdentity();
         int providerErrorCode;
         try {
-            providerErrorCode = mInjector.getLockSettingsService().armRebootEscrow();
+            LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+            if (lockSettings == null) {
+                Slog.e(TAG, "Failed to get lock settings service, skipping"
+                        + " armRebootEscrow");
+                return new RebootPreparationError(
+                        RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE,
+                        ARM_REBOOT_ERROR_NO_PROVIDER);
+            }
+            providerErrorCode = lockSettings.armRebootEscrow();
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
index 1dbe3e4..81bf29b 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
@@ -19,24 +19,20 @@
 import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_CANCELLED;
 
 import static com.android.server.rotationresolver.RotationResolverManagerService.RESOLUTION_UNAVAILABLE;
-import static com.android.server.rotationresolver.RotationResolverManagerService.getServiceConfigPackage;
 import static com.android.server.rotationresolver.RotationResolverManagerService.logRotationStats;
 
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.AppGlobals;
 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.CancellationSignal;
+import android.os.RemoteException;
 import android.rotationresolver.RotationResolverInternal;
 import android.service.rotationresolver.RotationResolutionRequest;
-import android.service.rotationresolver.RotationResolverService;
-import android.text.TextUtils;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
@@ -65,7 +61,6 @@
     @GuardedBy("mLock")
     RemoteRotationResolverService mRemoteService;
 
-    private static String sTestingPackage;
     private ComponentName mComponentName;
 
     RotationResolverManagerPerUserService(@NonNull RotationResolverManagerService main,
@@ -139,18 +134,6 @@
     }
 
     /**
-     * Set the testing package name.
-     *
-     * @param packageName the name of the package that implements {@link RotationResolverService}
-     *                    and is used for testing only.
-     */
-    @VisibleForTesting
-    void setTestingPackage(String packageName) {
-        sTestingPackage = packageName;
-        mComponentName = resolveRotationResolverService(getContext());
-    }
-
-    /**
      * get the currently bound component name.
      */
     @VisibleForTesting
@@ -158,63 +141,40 @@
         return mComponentName;
     }
 
-    /**
-     * Provides rotation resolver service component name at runtime, making sure it's provided
-     * by the system.
-     */
-    static ComponentName resolveRotationResolverService(Context context) {
-        String resolvedPackage;
-        int flags = PackageManager.MATCH_SYSTEM_ONLY;
-        if (!TextUtils.isEmpty(sTestingPackage)) {
-            // Testing Package is set.
-            resolvedPackage = sTestingPackage;
-            flags = PackageManager.GET_META_DATA;
-        } else {
-            final String serviceConfigPackage = getServiceConfigPackage(context);
-            if (!TextUtils.isEmpty(serviceConfigPackage)) {
-                resolvedPackage = serviceConfigPackage;
-            } else {
-                return null;
-            }
-        }
-
-        final Intent intent = new Intent(
-                RotationResolverService.SERVICE_INTERFACE).setPackage(resolvedPackage);
-
-        final ResolveInfo resolveInfo = context.getPackageManager().resolveServiceAsUser(intent,
-                flags, context.getUserId());
-        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-            Slog.wtf(TAG, String.format("Service %s not found in package %s",
-                    RotationResolverService.SERVICE_INTERFACE, resolvedPackage));
-            return null;
-        }
-
-        final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-        final String permission = serviceInfo.permission;
-        if (Manifest.permission.BIND_ROTATION_RESOLVER_SERVICE.equals(permission)) {
-            Slog.i(TAG, String.format("Successfully bound the service from package: %s",
-                    resolvedPackage));
-            return serviceInfo.getComponentName();
-        }
-        Slog.e(TAG, String.format(
-                "Service %s should require %s permission. Found %s permission",
-                serviceInfo.getComponentName(),
-                Manifest.permission.BIND_ROTATION_RESOLVER_SERVICE,
-                serviceInfo.permission));
-        return null;
-    }
-
 
     /** Resolves and sets up the rotation resolver service if it had not been done yet. */
     @GuardedBy("mLock")
     @VisibleForTesting
     boolean isServiceAvailableLocked() {
         if (mComponentName == null) {
-            mComponentName = resolveRotationResolverService(getContext());
+            mComponentName = updateServiceInfoLocked();
         }
         return mComponentName != null;
     }
 
+    @Override // from PerUserSystemService
+    protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
+            throws PackageManager.NameNotFoundException {
+        ServiceInfo serviceInfo;
+        try {
+            serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+                    PackageManager.GET_META_DATA, mUserId);
+            if (serviceInfo != null) {
+                final String permission = serviceInfo.permission;
+                if (!Manifest.permission.BIND_ROTATION_RESOLVER_SERVICE.equals(permission)) {
+                    throw new SecurityException(String.format(
+                            "Service %s requires %s permission. Found %s permission",
+                            serviceInfo.getComponentName(),
+                            Manifest.permission.BIND_ROTATION_RESOLVER_SERVICE,
+                            serviceInfo.permission));
+                }
+            }
+        } catch (RemoteException e) {
+            throw new PackageManager.NameNotFoundException(
+                    "Could not get service for " + serviceComponent);
+        }
+        return serviceInfo;
+    }
 
     @GuardedBy("mLock")
     private void cancelLocked() {
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
index a0e04ee..9f3f096 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
@@ -23,7 +23,6 @@
 import android.os.ShellCommand;
 import android.rotationresolver.RotationResolverInternal.RotationResolverCallbackInternal;
 import android.service.rotationresolver.RotationResolutionRequest;
-import android.text.TextUtils;
 import android.view.Surface;
 
 import java.io.PrintWriter;
@@ -75,12 +74,10 @@
                 return runResolveRotation();
             case "get-last-resolution":
                 return getLastResolution();
-            case "set-testing-package":
-                return setTestRotationResolverPackage(getNextArgRequired());
             case "get-bound-package":
                 return getBoundPackageName();
-            case "clear-testing-package":
-                return resetTestRotationResolverPackage();
+            case "set-temporary-service":
+                return setTemporaryService(getNextArgRequired());
             default:
                 return handleDefaultCommands(cmd);
         }
@@ -93,17 +90,18 @@
         return 0;
     }
 
-    private int setTestRotationResolverPackage(String testingPackage) {
-        if (!TextUtils.isEmpty((testingPackage))) {
-            mService.setTestingPackage(testingPackage);
-            sTestableRotationCallbackInternal.reset();
+    private int setTemporaryService(String serviceName) {
+        final PrintWriter out = getOutPrintWriter();
+        if (serviceName == null) {
+            mService.getMaster().resetTemporaryService(mService.getUserId());
+            out.println("RotationResolverService temporary reset. ");
+            return 0;
         }
-        return 0;
-    }
 
-    private int resetTestRotationResolverPackage() {
-        mService.setTestingPackage("");
-        sTestableRotationCallbackInternal.reset();
+        final int duration = Integer.parseInt(getNextArgRequired());
+        mService.getMaster().setTemporaryService(mService.getUserId(), serviceName, duration);
+        out.println("RotationResolverService temporarily set to " + serviceName
+                + " for " + duration + "ms");
         return 0;
     }
 
@@ -130,8 +128,9 @@
         pw.println();
         pw.println("  resolve-rotation: request a rotation resolution.");
         pw.println("  get-last-resolution: show the last rotation resolution result.");
-        pw.println("  set-testing-package: Set the testing package that implements the service.");
         pw.println("  get-bound-package: print the bound package that implements the service.");
-        pw.println("  clear-testing-package: reset the testing package.");
+        pw.println("  set-temporary-service [COMPONENT_NAME DURATION]");
+        pw.println("    Temporarily (for DURATION ms) changes the service implementation.");
+        pw.println("    To reset, call with no argument.");
     }
 }
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
index 6f0741d..c1f8240 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
@@ -133,6 +133,7 @@
      * Throws a {@link SecurityException} iff the originator has permission to receive data.
      */
     void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) {
+        // TODO(b/186164881): remove
         // START TEMP HACK
         enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO);
         int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index e37edeb..d6e7574 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -71,6 +71,7 @@
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.GcUtils;
 import com.android.internal.view.AppearanceRegion;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
@@ -649,6 +650,7 @@
     // ================================================================================
     // From IStatusBarService
     // ================================================================================
+
     @Override
     public void expandNotificationsPanel() {
         enforceExpandStatusBar();
@@ -971,6 +973,22 @@
         return new int[] {disable1, disable2};
     }
 
+    void runGcForTest() {
+        if (!Build.IS_DEBUGGABLE) {
+            throw new SecurityException("runGcForTest requires a debuggable build");
+        }
+
+        // Gc the system along the way
+        GcUtils.runGcAndFinalizersSync();
+
+        if (mBar != null) {
+            try {
+                mBar.runGcForTest();
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
     @Override
     public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
             String contentDescription) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
index 6171822..11a4976d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
@@ -75,6 +75,8 @@
                     return runSendDisableFlag();
                 case "tracing":
                     return runTracing();
+                case "run-gc":
+                    return runGc();
                 // Handle everything that would be handled in `handleDefaultCommand()` explicitly,
                 // so the default can be to pass all args to StatusBar
                 case "-h":
@@ -213,6 +215,11 @@
         return 0;
     }
 
+    private int runGc() {
+        mInterface.runGcForTest();
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index e1747f7..f918827 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -50,6 +50,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
+import com.android.server.vcn.util.LogUtils;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -305,13 +306,13 @@
                 handleTeardown();
                 break;
             default:
-                Slog.wtf(getLogTag(), "Unknown msg.what: " + msg.what);
+                logWtf("Unknown msg.what: " + msg.what);
         }
     }
 
     private void handleConfigUpdated(@NonNull VcnConfig config) {
         // TODO: Add a dump function in VcnConfig that omits PII. Until then, use hashCode()
-        Slog.v(getLogTag(), "Config updated: config = " + config.hashCode());
+        logDbg("Config updated: old = " + mConfig.hashCode() + "; new = " + config.hashCode());
 
         mConfig = config;
 
@@ -326,8 +327,7 @@
             // connection details may have changed).
             if (!mConfig.getGatewayConnectionConfigs().contains(gatewayConnectionConfig)) {
                 if (gatewayConnection == null) {
-                    Slog.wtf(
-                            getLogTag(), "Found gatewayConnectionConfig without GatewayConnection");
+                    logWtf("Found gatewayConnectionConfig without GatewayConnection");
                 } else {
                     gatewayConnection.teardownAsynchronously();
                 }
@@ -340,6 +340,7 @@
     }
 
     private void handleTeardown() {
+        logDbg("Tearing down");
         mVcnContext.getVcnNetworkProvider().unregisterListener(mRequestListener);
 
         for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
@@ -350,6 +351,7 @@
     }
 
     private void handleSafeModeStatusChanged() {
+        logDbg("VcnGatewayConnection safe mode status changed");
         boolean hasSafeModeGatewayConnection = false;
 
         // If any VcnGatewayConnection is in safe mode, mark the entire VCN as being in safe mode
@@ -365,21 +367,19 @@
                 hasSafeModeGatewayConnection ? VCN_STATUS_CODE_SAFE_MODE : VCN_STATUS_CODE_ACTIVE;
         if (oldStatus != mCurrentStatus) {
             mVcnCallback.onSafeModeStatusChanged(hasSafeModeGatewayConnection);
+            logDbg(
+                    "Safe mode "
+                            + (mCurrentStatus == VCN_STATUS_CODE_SAFE_MODE ? "entered" : "exited"));
         }
     }
 
     private void handleNetworkRequested(@NonNull NetworkRequest request) {
-        Slog.v(getLogTag(), "Received request " + request);
+        logVdbg("Received request " + request);
 
         // If preexisting VcnGatewayConnection(s) satisfy request, return
         for (VcnGatewayConnectionConfig gatewayConnectionConfig : mVcnGatewayConnections.keySet()) {
             if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
-                if (VDBG) {
-                    Slog.v(
-                            getLogTag(),
-                            "Request already satisfied by existing VcnGatewayConnection: "
-                                    + request);
-                }
+                logDbg("Request already satisfied by existing VcnGatewayConnection: " + request);
                 return;
             }
         }
@@ -389,7 +389,7 @@
         for (VcnGatewayConnectionConfig gatewayConnectionConfig :
                 mConfig.getGatewayConnectionConfigs()) {
             if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
-                Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
+                logDbg("Bringing up new VcnGatewayConnection for request " + request);
 
                 if (getExposedCapabilitiesForMobileDataState(gatewayConnectionConfig).isEmpty()) {
                     // Skip; this network does not provide any services if mobile data is disabled.
@@ -400,8 +400,9 @@
                 // pre-existing VcnGatewayConnections that satisfy a given request, but if state
                 // that affects the satsifying of requests changes, this is theoretically possible.
                 if (mVcnGatewayConnections.containsKey(gatewayConnectionConfig)) {
-                    Slog.wtf(getLogTag(), "Attempted to bring up VcnGatewayConnection for config "
-                            + "with existing VcnGatewayConnection");
+                    logWtf(
+                            "Attempted to bring up VcnGatewayConnection for config "
+                                    + "with existing VcnGatewayConnection");
                     return;
                 }
 
@@ -414,8 +415,12 @@
                                 new VcnGatewayStatusCallbackImpl(gatewayConnectionConfig),
                                 mIsMobileDataEnabled);
                 mVcnGatewayConnections.put(gatewayConnectionConfig, vcnGatewayConnection);
+
+                return;
             }
         }
+
+        logVdbg("Request could not be fulfilled by VCN: " + request);
     }
 
     private Set<Integer> getExposedCapabilitiesForMobileDataState(
@@ -432,7 +437,7 @@
     }
 
     private void handleGatewayConnectionQuit(VcnGatewayConnectionConfig config) {
-        Slog.v(getLogTag(), "VcnGatewayConnection quit: " + config);
+        logDbg("VcnGatewayConnection quit: " + config);
         mVcnGatewayConnections.remove(config);
 
         // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be satisfied
@@ -467,9 +472,7 @@
                 if (exposedCaps.contains(NET_CAPABILITY_INTERNET)
                         || exposedCaps.contains(NET_CAPABILITY_DUN)) {
                     if (gatewayConnection == null) {
-                        Slog.wtf(
-                                getLogTag(),
-                                "Found gatewayConnectionConfig without GatewayConnection");
+                        logWtf("Found gatewayConnectionConfig without" + " GatewayConnection");
                     } else {
                         // TODO(b/184868850): Optimize by restarting NetworkAgents without teardown.
                         gatewayConnection.teardownAsynchronously();
@@ -479,6 +482,8 @@
 
             // Trigger re-evaluation of all requests; mobile data state impacts supported caps.
             mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
+
+            logDbg("Mobile data " + (mIsMobileDataEnabled ? "enabled" : "disabled"));
         }
     }
 
@@ -507,8 +512,38 @@
         return request.canBeSatisfiedBy(builder.build());
     }
 
-    private String getLogTag() {
-        return TAG + " [" + mSubscriptionGroup.hashCode() + "]";
+    private String getLogPrefix() {
+        return "[" + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup) + "]: ";
+    }
+
+    private void logVdbg(String msg) {
+        if (VDBG) {
+            Slog.v(TAG, getLogPrefix() + msg);
+        }
+    }
+
+    private void logDbg(String msg) {
+        Slog.d(TAG, getLogPrefix() + msg);
+    }
+
+    private void logDbg(String msg, Throwable tr) {
+        Slog.d(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logErr(String msg) {
+        Slog.e(TAG, getLogPrefix() + msg);
+    }
+
+    private void logErr(String msg, Throwable tr) {
+        Slog.e(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logWtf(String msg) {
+        Slog.wtf(TAG, getLogPrefix() + msg);
+    }
+
+    private void logWtf(String msg, Throwable tr) {
+        Slog.wtf(TAG, getLogPrefix() + msg, tr);
     }
 
     /**
@@ -521,6 +556,7 @@
         pw.increaseIndent();
 
         pw.println("mCurrentStatus: " + mCurrentStatus);
+        pw.println("mIsMobileDataEnabled: " + mIsMobileDataEnabled);
 
         pw.println("mVcnGatewayConnections:");
         for (VcnGatewayConnection gw : mVcnGatewayConnections.values()) {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 65b947c..5cecff6 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -88,6 +88,7 @@
 import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
 import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
+import com.android.server.vcn.util.LogUtils;
 import com.android.server.vcn.util.MtuUtils;
 
 import java.io.IOException;
@@ -701,6 +702,7 @@
      * <p>Once torn down, this VcnTunnel CANNOT be started again.
      */
     public void teardownAsynchronously() {
+        logDbg("Triggering async teardown");
         sendDisconnectRequestedAndAcquireWakelock(
                 DISCONNECT_REASON_TEARDOWN, true /* shouldQuit */);
 
@@ -710,6 +712,8 @@
 
     @Override
     protected void onQuitting() {
+        logDbg("Quitting VcnGatewayConnection");
+
         // No need to call setInterfaceDown(); the IpSecInterface is being fully torn down.
         if (mTunnelIface != null) {
             mTunnelIface.close();
@@ -750,6 +754,10 @@
             // TODO(b/180132994): explore safely removing this Thread check
             mVcnContext.ensureRunningOnLooperThread();
 
+            logDbg(
+                    "Selected underlying network changed: "
+                            + (underlying == null ? null : underlying.network));
+
             // TODO(b/179091925): Move the delayed-message handling to BaseState
 
             // If underlying is null, all underlying networks have been lost. Disconnect VCN after a
@@ -774,6 +782,8 @@
 
         if (!mIsQuitting) {
             mWakeLock.acquire();
+
+            logVdbg("Wakelock acquired: " + mWakeLock);
         }
     }
 
@@ -781,6 +791,8 @@
         mVcnContext.ensureRunningOnLooperThread();
 
         mWakeLock.release();
+
+        logVdbg("Wakelock released: " + mWakeLock);
     }
 
     /**
@@ -798,8 +810,7 @@
 
     @Override
     public void sendMessage(int what) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what);
@@ -807,8 +818,7 @@
 
     @Override
     public void sendMessage(int what, Object obj) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, obj);
@@ -816,8 +826,7 @@
 
     @Override
     public void sendMessage(int what, int arg1) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1);
@@ -825,8 +834,7 @@
 
     @Override
     public void sendMessage(int what, int arg1, int arg2) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1, arg2);
@@ -834,8 +842,7 @@
 
     @Override
     public void sendMessage(int what, int arg1, int arg2, Object obj) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1, arg2, obj);
@@ -843,8 +850,7 @@
 
     @Override
     public void sendMessage(Message msg) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(msg);
@@ -935,10 +941,14 @@
     }
 
     private void setTeardownTimeoutAlarm() {
+        logVdbg("Setting teardown timeout alarm; mCurrentToken: " + mCurrentToken);
+
         // Safe to assign this alarm because it is either 1) already null, or 2) already fired. In
         // either case, there is nothing to cancel.
         if (mTeardownTimeoutAlarm != null) {
-            Slog.wtf(TAG, "mTeardownTimeoutAlarm should be null before being set");
+            logWtf(
+                    "mTeardownTimeoutAlarm should be null before being set; mCurrentToken: "
+                            + mCurrentToken);
         }
 
         final Message delayedMessage = obtainMessage(EVENT_TEARDOWN_TIMEOUT_EXPIRED, mCurrentToken);
@@ -950,6 +960,8 @@
     }
 
     private void cancelTeardownTimeoutAlarm() {
+        logVdbg("Cancelling teardown timeout alarm; mCurrentToken: " + mCurrentToken);
+
         if (mTeardownTimeoutAlarm != null) {
             mTeardownTimeoutAlarm.cancel();
             mTeardownTimeoutAlarm = null;
@@ -960,6 +972,11 @@
     }
 
     private void setDisconnectRequestAlarm() {
+        logVdbg(
+                "Setting alarm to disconnect due to underlying network loss;"
+                        + " mCurrentToken: "
+                        + mCurrentToken);
+
         // Only schedule a NEW alarm if none is already set.
         if (mDisconnectRequestAlarm != null) {
             return;
@@ -980,6 +997,11 @@
     }
 
     private void cancelDisconnectRequestAlarm() {
+        logVdbg(
+                "Cancelling alarm to disconnect due to underlying network loss;"
+                        + " mCurrentToken: "
+                        + mCurrentToken);
+
         if (mDisconnectRequestAlarm != null) {
             mDisconnectRequestAlarm.cancel();
             mDisconnectRequestAlarm = null;
@@ -993,10 +1015,14 @@
     }
 
     private void setRetryTimeoutAlarm(long delay) {
+        logVdbg("Setting retry alarm; mCurrentToken: " + mCurrentToken);
+
         // Safe to assign this alarm because it is either 1) already null, or 2) already fired. In
         // either case, there is nothing to cancel.
         if (mRetryTimeoutAlarm != null) {
-            Slog.wtf(TAG, "mRetryTimeoutAlarm should be null before being set");
+            logWtf(
+                    "mRetryTimeoutAlarm should be null before being set; mCurrentToken: "
+                            + mCurrentToken);
         }
 
         final Message delayedMessage = obtainMessage(EVENT_RETRY_TIMEOUT_EXPIRED, mCurrentToken);
@@ -1004,6 +1030,8 @@
     }
 
     private void cancelRetryTimeoutAlarm() {
+        logVdbg("Cancel retry alarm; mCurrentToken: " + mCurrentToken);
+
         if (mRetryTimeoutAlarm != null) {
             mRetryTimeoutAlarm.cancel();
             mRetryTimeoutAlarm = null;
@@ -1014,6 +1042,8 @@
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     void setSafeModeAlarm() {
+        logVdbg("Setting safe mode alarm; mCurrentToken: " + mCurrentToken);
+
         // Only schedule a NEW alarm if none is already set.
         if (mSafeModeTimeoutAlarm != null) {
             return;
@@ -1028,6 +1058,8 @@
     }
 
     private void cancelSafeModeAlarm() {
+        logVdbg("Cancel safe mode alarm; mCurrentToken: " + mCurrentToken);
+
         if (mSafeModeTimeoutAlarm != null) {
             mSafeModeTimeoutAlarm.cancel();
             mSafeModeTimeoutAlarm = null;
@@ -1092,6 +1124,14 @@
                             + exception.getMessage();
         }
 
+        logDbg(
+                "Encountered error; code="
+                        + errorCode
+                        + ", exceptionClass="
+                        + exceptionClass
+                        + ", exceptionMessage="
+                        + exceptionMessage);
+
         mGatewayStatusCallback.onGatewayConnectionError(
                 mConnectionConfig.getGatewayConnectionName(),
                 errorCode,
@@ -1137,7 +1177,7 @@
             try {
                 enterState();
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1169,14 +1209,14 @@
         public final boolean processMessage(Message msg) {
             final int token = msg.arg1;
             if (!isValidToken(token)) {
-                Slog.v(TAG, "Message called with obsolete token: " + token + "; what: " + msg.what);
+                logDbg("Message called with obsolete token: " + token + "; what: " + msg.what);
                 return HANDLED;
             }
 
             try {
                 processStateMsg(msg);
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1194,7 +1234,7 @@
             try {
                 exitState();
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1234,7 +1274,7 @@
         protected void handleDisconnectRequested(EventDisconnectRequestedInfo info) {
             // TODO(b/180526152): notify VcnStatusCallback for Network loss
 
-            Slog.v(TAG, "Tearing down. Cause: " + info.reason);
+            logDbg("Tearing down. Cause: " + info.reason);
             mIsQuitting = info.shouldQuit;
 
             teardownNetwork();
@@ -1250,6 +1290,7 @@
 
         protected void handleSafeModeTimeoutExceeded() {
             mSafeModeTimeoutAlarm = null;
+            logDbg("Entering safe mode after timeout exceeded");
 
             // Connectivity for this GatewayConnection is broken; tear down the Network.
             teardownNetwork();
@@ -1258,13 +1299,15 @@
         }
 
         protected void logUnexpectedEvent(int what) {
-            Slog.d(TAG, String.format(
-                    "Unexpected event code %d in state %s", what, this.getClass().getSimpleName()));
+            logDbg(
+                    "Unexpected event code "
+                            + what
+                            + " in state "
+                            + this.getClass().getSimpleName());
         }
 
         protected void logWtfUnknownEvent(int what) {
-            Slog.wtf(TAG, String.format(
-                    "Unknown event code %d in state %s", what, this.getClass().getSimpleName()));
+            logWtf("Unknown event code " + what + " in state " + this.getClass().getSimpleName());
         }
     }
 
@@ -1281,7 +1324,7 @@
             }
 
             if (mIkeSession != null || mNetworkAgent != null) {
-                Slog.wtf(TAG, "Active IKE Session or NetworkAgent in DisconnectedState");
+                logWtf("Active IKE Session or NetworkAgent in DisconnectedState");
             }
 
             cancelSafeModeAlarm();
@@ -1349,7 +1392,7 @@
         @Override
         protected void enterState() throws Exception {
             if (mIkeSession == null) {
-                Slog.wtf(TAG, "IKE session was already closed when entering Disconnecting state.");
+                logWtf("IKE session was already closed when entering Disconnecting state.");
                 sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, mCurrentToken);
                 return;
             }
@@ -1436,7 +1479,7 @@
         @Override
         protected void enterState() {
             if (mIkeSession != null) {
-                Slog.wtf(TAG, "ConnectingState entered with active session");
+                logWtf("ConnectingState entered with active session");
 
                 // Attempt to recover.
                 mIkeSession.kill();
@@ -1455,7 +1498,7 @@
 
                     if (oldUnderlying == null) {
                         // This should never happen, but if it does, there's likely a nasty bug.
-                        Slog.wtf(TAG, "Old underlying network was null in connected state. Bug?");
+                        logWtf("Old underlying network was null in connected state. Bug?");
                     }
 
                     // If new underlying is null, all underlying networks have been lost; disconnect
@@ -1550,11 +1593,11 @@
                                 // new NetworkAgent replaces an old one before the unwanted() call
                                 // is processed.
                                 if (mNetworkAgent != agentRef) {
-                                    Slog.d(TAG, "unwanted() called on stale NetworkAgent");
+                                    logDbg("unwanted() called on stale NetworkAgent");
                                     return;
                                 }
 
-                                Slog.d(TAG, "NetworkAgent was unwanted");
+                                logDbg("NetworkAgent was unwanted");
                                 teardownAsynchronously();
                             } /* networkUnwantedCallback */,
                             (status) -> {
@@ -1568,8 +1611,7 @@
                                         setSafeModeAlarm();
                                         break;
                                     default:
-                                        Slog.wtf(
-                                                TAG,
+                                        logWtf(
                                                 "Unknown validation status "
                                                         + status
                                                         + "; ignoring");
@@ -1602,13 +1644,26 @@
                 @NonNull Network underlyingNetwork,
                 @NonNull IpSecTransform transform,
                 int direction) {
+            if (direction != IpSecManager.DIRECTION_IN && direction != IpSecManager.DIRECTION_OUT) {
+                Slog.wtf(TAG, "Applying transform for unexpected direction: " + direction);
+            }
+
             try {
                 tunnelIface.setUnderlyingNetwork(underlyingNetwork);
 
                 // Transforms do not need to be persisted; the IkeSession will keep them alive
                 mIpSecManager.applyTunnelModeTransform(tunnelIface, direction, transform);
+
+                // For inbound transforms, additionally allow forwarded traffic to bridge to DUN (as
+                // needed)
+                final Set<Integer> exposedCaps = mConnectionConfig.getAllExposedCapabilities();
+                if (direction == IpSecManager.DIRECTION_IN
+                        && exposedCaps.contains(NET_CAPABILITY_DUN)) {
+                    mIpSecManager.applyTunnelModeTransform(
+                            tunnelIface, IpSecManager.DIRECTION_FWD, transform);
+                }
             } catch (IOException e) {
-                Slog.d(TAG, "Transform application failed for network " + token, e);
+                logDbg("Transform application failed for network " + token, e);
                 sessionLost(token, e);
             }
         }
@@ -1642,7 +1697,7 @@
                     tunnelIface.removeAddress(address.getAddress(), address.getPrefixLength());
                 }
             } catch (IOException e) {
-                Slog.d(TAG, "Adding address to tunnel failed for token " + token, e);
+                logDbg("Adding address to tunnel failed for token " + token, e);
                 sessionLost(token, e);
             }
         }
@@ -1722,6 +1777,8 @@
         }
 
         private void handleMigrationCompleted(EventMigrationCompletedInfo migrationCompletedInfo) {
+            logDbg("Migration completed: " + mUnderlying.network);
+
             applyTransform(
                     mCurrentToken,
                     mTunnelIface,
@@ -1744,6 +1801,8 @@
             mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying;
 
             if (mUnderlying == null) {
+                logDbg("Underlying network lost");
+
                 // Ignored for now; a new network may be coming up. If none does, the delayed
                 // NETWORK_LOST disconnect will be fired, and tear down the session + network.
                 return;
@@ -1752,7 +1811,7 @@
             // mUnderlying assumed non-null, given check above.
             // If network changed, migrate. Otherwise, update any existing networkAgent.
             if (oldUnderlying == null || !oldUnderlying.network.equals(mUnderlying.network)) {
-                Slog.v(TAG, "Migrating to new network: " + mUnderlying.network);
+                logDbg("Migrating to new network: " + mUnderlying.network);
                 mIkeSession.setNetwork(mUnderlying.network);
             } else {
                 // oldUnderlying is non-null & underlying network itself has not changed
@@ -1803,7 +1862,7 @@
             mFailedAttempts++;
 
             if (mUnderlying == null) {
-                Slog.wtf(TAG, "Underlying network was null in retry state");
+                logWtf("Underlying network was null in retry state");
                 transitionTo(mDisconnectedState);
             } else {
                 // Safe to blindly set up, as it is cancelled and cleared on exiting this state
@@ -1973,25 +2032,25 @@
 
         @Override
         public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
-            Slog.v(TAG, "IkeOpened for token " + mToken);
+            logDbg("IkeOpened for token " + mToken);
             // Nothing to do here.
         }
 
         @Override
         public void onClosed() {
-            Slog.v(TAG, "IkeClosed for token " + mToken);
+            logDbg("IkeClosed for token " + mToken);
             sessionClosed(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Slog.v(TAG, "IkeClosedExceptionally for token " + mToken, exception);
+            logDbg("IkeClosedExceptionally for token " + mToken, exception);
             sessionClosed(mToken, exception);
         }
 
         @Override
         public void onError(@NonNull IkeProtocolException exception) {
-            Slog.v(TAG, "IkeError for token " + mToken, exception);
+            logDbg("IkeError for token " + mToken, exception);
             // Non-fatal, log and continue.
         }
     }
@@ -2008,7 +2067,7 @@
         /** Internal proxy method for injecting of mocked ChildSessionConfiguration */
         @VisibleForTesting(visibility = Visibility.PRIVATE)
         void onOpened(@NonNull VcnChildSessionConfiguration childConfig) {
-            Slog.v(TAG, "ChildOpened for token " + mToken);
+            logDbg("ChildOpened for token " + mToken);
             childOpened(mToken, childConfig);
         }
 
@@ -2019,19 +2078,19 @@
 
         @Override
         public void onClosed() {
-            Slog.v(TAG, "ChildClosed for token " + mToken);
+            logDbg("ChildClosed for token " + mToken);
             sessionLost(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Slog.v(TAG, "ChildClosedExceptionally for token " + mToken, exception);
+            logDbg("ChildClosedExceptionally for token " + mToken, exception);
             sessionLost(mToken, exception);
         }
 
         @Override
         public void onIpSecTransformCreated(@NonNull IpSecTransform transform, int direction) {
-            Slog.v(TAG, "ChildTransformCreated; Direction: " + direction + "; token " + mToken);
+            logDbg("ChildTransformCreated; Direction: " + direction + "; token " + mToken);
             childTransformCreated(mToken, transform, direction);
         }
 
@@ -2039,7 +2098,7 @@
         public void onIpSecTransformsMigrated(
                 @NonNull IpSecTransform inIpSecTransform,
                 @NonNull IpSecTransform outIpSecTransform) {
-            Slog.v(TAG, "ChildTransformsMigrated; token " + mToken);
+            logDbg("ChildTransformsMigrated; token " + mToken);
             migrationCompleted(mToken, inIpSecTransform, outIpSecTransform);
         }
 
@@ -2047,10 +2106,48 @@
         public void onIpSecTransformDeleted(@NonNull IpSecTransform transform, int direction) {
             // Nothing to be done; no references to the IpSecTransform are held, and this transform
             // will be closed by the IKE library.
-            Slog.v(TAG, "ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
+            logDbg("ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
         }
     }
 
+    private String getLogPrefix() {
+        return "["
+                + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup)
+                + "-"
+                + mConnectionConfig.getGatewayConnectionName()
+                + "]: ";
+    }
+
+    private void logVdbg(String msg) {
+        if (VDBG) {
+            Slog.v(TAG, getLogPrefix() + msg);
+        }
+    }
+
+    private void logDbg(String msg) {
+        Slog.d(TAG, getLogPrefix() + msg);
+    }
+
+    private void logDbg(String msg, Throwable tr) {
+        Slog.d(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logErr(String msg) {
+        Slog.e(TAG, getLogPrefix() + msg);
+    }
+
+    private void logErr(String msg, Throwable tr) {
+        Slog.e(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logWtf(String msg) {
+        Slog.wtf(TAG, getLogPrefix() + msg);
+    }
+
+    private void logWtf(String msg, Throwable tr) {
+        Slog.wtf(TAG, getLogPrefix() + msg, tr);
+    }
+
     /**
      * Dumps the state of this VcnGatewayConnection for logging and debugging purposes.
      *
diff --git a/services/core/java/com/android/server/vcn/util/LogUtils.java b/services/core/java/com/android/server/vcn/util/LogUtils.java
new file mode 100644
index 0000000..93728ce
--- /dev/null
+++ b/services/core/java/com/android/server/vcn/util/LogUtils.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vcn.util;
+
+import android.annotation.Nullable;
+import android.os.ParcelUuid;
+
+import com.android.internal.util.HexDump;
+
+/** @hide */
+public class LogUtils {
+    /**
+     * Returns the hash of the subscription group in hexadecimal format.
+     *
+     * @return the hexadecimal encoded string if uuid was non-null, else {@code null}
+     */
+    @Nullable
+    public static String getHashedSubscriptionGroup(@Nullable ParcelUuid uuid) {
+        if (uuid == null) {
+            return null;
+        }
+
+        return HexDump.toHexString(uuid.hashCode());
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index eeb7fac..47622bc 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -74,8 +74,8 @@
      */
     public abstract void addWindow(WindowToken token);
 
-    /** Gets the {@link DisplayArea} which a {@link WindowToken} is about to be attached to. */
-    public abstract DisplayArea.Tokens getDisplayAreaForWindowToken(int type, Bundle options,
+    /** Gets the {@link DisplayArea} with given window type and launched options */
+    public abstract DisplayArea.Tokens findAreaForWindowType(int type, Bundle options,
             boolean ownerCanManageAppTokens, boolean roundedCornerOverlay);
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index a7312b3..47d7c9d 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -756,7 +756,14 @@
         @VisibleForTesting
         DisplayArea.Tokens findAreaForToken(WindowToken token) {
             return mSelectRootForWindowFunc.apply(token.windowType, token.mOptions)
-                    .findAreaForToken(token);
+                    .findAreaForTokenInLayer(token);
+        }
+
+        @Override
+        public DisplayArea.Tokens findAreaForWindowType(int type, Bundle options,
+                boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
+            return mSelectRootForWindowFunc.apply(type, options).findAreaForWindowTypeInLayer(type,
+                    ownerCanManageAppTokens, roundedCornerOverlay);
         }
 
         @VisibleForTesting
@@ -794,13 +801,6 @@
         public TaskDisplayArea getDefaultTaskDisplayArea() {
             return mDefaultTaskDisplayArea;
         }
-
-        @Override
-        public DisplayArea.Tokens getDisplayAreaForWindowToken(int type, Bundle options,
-                boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
-            return mSelectRootForWindowFunc.apply(type, options).findAreaForToken(type,
-                    ownerCanManageAppTokens, roundedCornerOverlay);
-        }
     }
 
     static class PendingArea {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a108478..411059d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1123,15 +1123,8 @@
             token.mDisplayContent = this;
             // Add non-app token to container hierarchy on the display. App tokens are added through
             // the parent container managing them (e.g. Tasks).
-            switch (token.windowType) {
-                case TYPE_INPUT_METHOD:
-                case TYPE_INPUT_METHOD_DIALOG:
-                    mImeWindowsContainer.addChild(token);
-                    break;
-                default:
-                    mDisplayAreaPolicy.addWindow(token);
-                    break;
-            }
+            final DisplayArea.Tokens da = findAreaForToken(token).asTokens();
+            da.addChild(token);
         }
     }
 
@@ -5982,7 +5975,7 @@
         return mMagnificationSpec;
     }
 
-    DisplayArea getAreaForWindowToken(int windowType, Bundle options,
+    DisplayArea findAreaForWindowType(int windowType, Bundle options,
             boolean ownerCanManageAppToken, boolean roundedCornerOverlay) {
         // TODO(b/159767464): figure out how to find an appropriate TDA.
         if (windowType >= FIRST_APPLICATION_WINDOW && windowType <= LAST_APPLICATION_WINDOW) {
@@ -5994,10 +5987,28 @@
         if (windowType == TYPE_INPUT_METHOD || windowType == TYPE_INPUT_METHOD_DIALOG) {
             return getImeContainer();
         }
-        return mDisplayAreaPolicy.getDisplayAreaForWindowToken(windowType, options,
+        return mDisplayAreaPolicy.findAreaForWindowType(windowType, options,
                 ownerCanManageAppToken, roundedCornerOverlay);
     }
 
+    /**
+     * Finds the {@link DisplayArea} for the {@link WindowToken} to attach to.
+     * <p>
+     * Note that the differences between this API and
+     * {@link RootDisplayArea#findAreaForTokenInLayer(WindowToken)} is that this API finds a
+     * {@link DisplayArea} in {@link DisplayContent} level, which may find a {@link DisplayArea}
+     * from multiple {@link RootDisplayArea RootDisplayAreas} under this {@link DisplayContent}'s
+     * hierarchy, while {@link RootDisplayArea#findAreaForTokenInLayer(WindowToken)} finds a
+     * {@link DisplayArea.Tokens} from a {@link DisplayArea.Tokens} list mapped to window layers.
+     * </p>
+     *
+     * @see DisplayContent#findAreaForTokenInLayer(WindowToken)
+     */
+    DisplayArea findAreaForToken(WindowToken windowToken) {
+        return findAreaForWindowType(windowToken.getWindowType(), windowToken.mOptions,
+                windowToken.mOwnerCanManageAppTokens, windowToken.mRoundedCornerOverlay);
+    }
+
     @Override
     DisplayContent asDisplayContent() {
         return this;
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index dea83f0..7b4b23e 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -257,15 +257,16 @@
             // be rotated.
             float dx = pipTx.mPositionX;
             float dy = pipTx.mPositionY;
+            final Matrix matrix = pipTx.getMatrix();
             if (pipTx.mRotation == 90) {
                 dx = pipTx.mPositionY;
                 dy = areaBounds.right - pipTx.mPositionX;
+                matrix.postRotate(-90);
             } else if (pipTx.mRotation == -90) {
                 dx = areaBounds.bottom - pipTx.mPositionY;
                 dy = pipTx.mPositionX;
+                matrix.postRotate(90);
             }
-            final Matrix matrix = new Matrix();
-            matrix.setScale(pipTx.mScaleX, pipTx.mScaleY);
             matrix.postTranslate(dx, dy);
             t.setMatrix(pinnedTask.getSurfaceControl(), matrix, new float[9]);
             Slog.i(TAG, "Seamless rotation PiP tx=" + pipTx + " pos=" + dx + "," + dy);
diff --git a/services/core/java/com/android/server/wm/RootDisplayArea.java b/services/core/java/com/android/server/wm/RootDisplayArea.java
index 1cda8d5..d94bb9e 100644
--- a/services/core/java/com/android/server/wm/RootDisplayArea.java
+++ b/services/core/java/com/android/server/wm/RootDisplayArea.java
@@ -101,15 +101,24 @@
                 "There is no FEATURE_IME_PLACEHOLDER in this root to place the IME container");
     }
 
-    /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */
+    /**
+     * Finds the {@link DisplayArea.Tokens} in {@code mAreaForLayer} that this type of window
+     * should be attached to.
+     * <p>
+     * Note that in most cases, users are expected to call
+     * {@link DisplayContent#findAreaForToken(WindowToken)} to find a {@link DisplayArea} in
+     * {@link DisplayContent} level instead of calling this inner method.
+     * </p>
+     */
     @Nullable
-    DisplayArea.Tokens findAreaForToken(WindowToken token) {
-        return findAreaForToken(token.windowType, token.mOwnerCanManageAppTokens,
+    DisplayArea.Tokens findAreaForTokenInLayer(WindowToken token) {
+        return findAreaForWindowTypeInLayer(token.windowType, token.mOwnerCanManageAppTokens,
                 token.mRoundedCornerOverlay);
     }
 
+    /** @see #findAreaForTokenInLayer(WindowToken)  */
     @Nullable
-    DisplayArea.Tokens findAreaForToken(int windowType, boolean ownerCanManageAppTokens,
+    DisplayArea.Tokens findAreaForWindowTypeInLayer(int windowType, boolean ownerCanManageAppTokens,
             boolean roundedCornerOverlay) {
         int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
                 ownerCanManageAppTokens, roundedCornerOverlay);
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index b417832..bc53041 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -201,7 +201,9 @@
             return mContainer;
         }
 
-        private void updateContainer(WindowContainer newContainer) {
+        private void updateContainer(@NonNull WindowContainer newContainer) {
+            Objects.requireNonNull(newContainer);
+
             if (mContainer.equals(newContainer)) {
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d43a763..ab5e498 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2688,7 +2688,7 @@
                 }
                 // TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
                 // the feature b/155340867 is completed.
-                final DisplayArea da = dc.getAreaForWindowToken(type, options,
+                final DisplayArea da = dc.findAreaForWindowType(type, options,
                         callerCanManageAppTokens, false /* roundedCornerOverlay */);
                 mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
                         callingUid, type, options);
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 7234281..5222511 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -2403,6 +2403,34 @@
     }
 
     @Test
+    public void opScheduleExactAlarmGranted() throws Exception {
+        final long durationMs = 20000L;
+        when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
+
+        mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
+        mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+
+        verify(mMockContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.SYSTEM),
+                isNull(), bundleCaptor.capture());
+
+        // Validate the intent.
+        assertEquals(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
+                intentCaptor.getValue().getAction());
+        assertEquals(TEST_CALLING_PACKAGE, intentCaptor.getValue().getPackage());
+
+        // Validate the options.
+        final BroadcastOptions bOptions = new BroadcastOptions(bundleCaptor.getValue());
+        assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+                bOptions.getTemporaryAppAllowlistType());
+        assertEquals(durationMs, bOptions.getTemporaryAppAllowlistDuration());
+        assertEquals(PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
+                bOptions.getTemporaryAppAllowlistReasonCode());
+    }
+
+    @Test
     public void removeExactAlarmsOnPermissionRevoked() {
         doReturn(true).when(
                 () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
index 5c7ccfc..2d03981 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
@@ -265,4 +265,36 @@
         assertThat(sStats.getDocumentRetrievingLatencyMillis())
                 .isEqualTo(nativeDocumentRetrievingLatencyMillis);
     }
+
+    @Test
+    public void testAppSearchStats_SetSchemaStats() {
+        int nativeLatencyMillis = 1;
+        int newTypeCount = 2;
+        int compatibleTypeChangeCount = 3;
+        int indexIncompatibleTypeChangeCount = 4;
+        int backwardsIncompatibleTypeChangeCount = 5;
+        final SetSchemaStats sStats =
+                new SetSchemaStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+                        .setStatusCode(TEST_STATUS_CODE)
+                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
+                        .setNativeLatencyMillis(nativeLatencyMillis)
+                        .setNewTypeCount(newTypeCount)
+                        .setCompatibleTypeChangeCount(compatibleTypeChangeCount)
+                        .setIndexIncompatibleTypeChangeCount(indexIncompatibleTypeChangeCount)
+                        .setBackwardsIncompatibleTypeChangeCount(
+                                backwardsIncompatibleTypeChangeCount)
+                        .build();
+
+        assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+        assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
+        assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+        assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+        assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
+        assertThat(sStats.getNewTypeCount()).isEqualTo(newTypeCount);
+        assertThat(sStats.getCompatibleTypeChangeCount()).isEqualTo(compatibleTypeChangeCount);
+        assertThat(sStats.getIndexIncompatibleTypeChangeCount())
+                .isEqualTo(indexIncompatibleTypeChangeCount);
+        assertThat(sStats.getBackwardsIncompatibleTypeChangeCount())
+                .isEqualTo(backwardsIncompatibleTypeChangeCount);
+    }
 }
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 7b48037..5caff3d 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
@@ -90,6 +90,10 @@
             String content = FileUtils.readTextFile(file, 100, "");
             return Long.parseLong(content.split(",")[1]);
         }
+
+        @Override
+        public void tryToCreateTypeface(File file) throws IOException {
+        }
     }
 
     // FakeFsverityUtil will successfully set up fake fs-verity if the signature is GOOD_SIGNATURE.
@@ -717,6 +721,10 @@
                     public long getRevision(File file) throws IOException {
                         return 0;
                     }
+
+                    @Override
+                    public void tryToCreateTypeface(File file) throws IOException {
+                    }
                 }, fakeFsverityUtil, mConfigFile, mCurrentTimeSupplier, mConfigSupplier);
         dir.loadFontFileMap();
 
@@ -751,6 +759,50 @@
                     public long getRevision(File file) throws IOException {
                         return 0;
                     }
+
+                    @Override
+                    public void tryToCreateTypeface(File file) throws IOException {
+                    }
+                }, fakeFsverityUtil, mConfigFile, mCurrentTimeSupplier, mConfigSupplier);
+        dir.loadFontFileMap();
+
+        try {
+            dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1,foo",
+                    GOOD_SIGNATURE)));
+            fail("Expect SystemFontException");
+        } catch (FontManagerService.SystemFontException e) {
+            assertThat(e.getErrorCode())
+                    .isEqualTo(FontManager.RESULT_ERROR_INVALID_FONT_FILE);
+        }
+        assertThat(dir.getPostScriptMap()).isEmpty();
+    }
+
+    @Test
+    public void installFontFile_failedToCreateTypeface() throws Exception {
+        FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
+        FakeFontFileParser parser = new FakeFontFileParser();
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir,
+                new UpdatableFontDir.FontFileParser() {
+                    @Override
+                    public String getPostScriptName(File file) throws IOException {
+                        return parser.getPostScriptName(file);
+                    }
+
+                    @Override
+                    public String buildFontFileName(File file) throws IOException {
+                        return parser.buildFontFileName(file);
+                    }
+
+                    @Override
+                    public long getRevision(File file) throws IOException {
+                        return parser.getRevision(file);
+                    }
+
+                    @Override
+                    public void tryToCreateTypeface(File file) throws IOException {
+                        throw new IOException();
+                    }
                 }, fakeFsverityUtil, mConfigFile, mCurrentTimeSupplier, mConfigSupplier);
         dir.loadFontFileMap();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 2c3f52e..4509ff4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -268,7 +268,7 @@
 
         // By default, the ime container is attached to DC as defined in DAPolicy.
         assertThat(imeContainer.getRootDisplayArea()).isEqualTo(mDisplay);
-        assertThat(mDisplay.findAreaForToken(imeToken)).isEqualTo(imeContainer);
+        assertThat(mDisplay.findAreaForTokenInLayer(imeToken)).isEqualTo(imeContainer);
 
         final WindowState firstActivityWin =
                 createWindow(null /* parent */, TYPE_APPLICATION_STARTING, mFirstActivity,
@@ -290,9 +290,9 @@
         assertThat(imeContainer.getRootDisplayArea()).isEqualTo(mFirstRoot);
         assertThat(imeContainer.getParent().asDisplayArea().mFeatureId)
                 .isEqualTo(FEATURE_IME_PLACEHOLDER);
-        assertThat(mDisplay.findAreaForToken(imeToken)).isNull();
-        assertThat(mFirstRoot.findAreaForToken(imeToken)).isEqualTo(imeContainer);
-        assertThat(mSecondRoot.findAreaForToken(imeToken)).isNull();
+        assertThat(mDisplay.findAreaForTokenInLayer(imeToken)).isNull();
+        assertThat(mFirstRoot.findAreaForTokenInLayer(imeToken)).isEqualTo(imeContainer);
+        assertThat(mSecondRoot.findAreaForTokenInLayer(imeToken)).isNull();
 
         // secondActivityWin should be the target
         doReturn(false).when(firstActivityWin).canBeImeTarget();
@@ -305,9 +305,9 @@
         assertThat(imeContainer.getRootDisplayArea()).isEqualTo(mSecondRoot);
         assertThat(imeContainer.getParent().asDisplayArea().mFeatureId)
                 .isEqualTo(FEATURE_IME_PLACEHOLDER);
-        assertThat(mDisplay.findAreaForToken(imeToken)).isNull();
-        assertThat(mFirstRoot.findAreaForToken(imeToken)).isNull();
-        assertThat(mSecondRoot.findAreaForToken(imeToken)).isEqualTo(imeContainer);
+        assertThat(mDisplay.findAreaForTokenInLayer(imeToken)).isNull();
+        assertThat(mFirstRoot.findAreaForTokenInLayer(imeToken)).isNull();
+        assertThat(mSecondRoot.findAreaForTokenInLayer(imeToken)).isEqualTo(imeContainer);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index 5d0fe17..e5eba57 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -19,6 +19,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -38,6 +39,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /**
  * Build/Install/Run:
@@ -185,6 +187,41 @@
         assertThat(mController.getContainer(mClientToken)).isEqualTo(da);
     }
 
+    @Test
+    public void testImeSwitchDialogWindowTokenRemovedOnDualDisplayContent_ListenToImeContainer() {
+        // Let the Display to be created with the DualDisplay policy.
+        final DisplayAreaPolicy.Provider policyProvider =
+                new DualDisplayAreaGroupPolicyTest.DualDisplayTestPolicyProvider();
+        Mockito.doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
+        // Create a DisplayContent with dual RootDisplayArea
+        DualDisplayAreaGroupPolicyTest.DualDisplayContent dualDisplayContent =
+                new DualDisplayAreaGroupPolicyTest.DualDisplayContent
+                 .Builder(mAtm, 1000, 1000).build();
+        final DisplayArea.Tokens imeContainer = dualDisplayContent.getImeContainer();
+        // Put the ImeContainer to the first sub-RootDisplayArea
+        dualDisplayContent.mFirstRoot.placeImeContainer(imeContainer);
+
+        assertThat(imeContainer.getRootDisplayArea()).isEqualTo(dualDisplayContent.mFirstRoot);
+
+        // Simulate the behavior to show IME switch dialog: its context switches to register to
+        // context created WindowToken.
+        WindowToken windowContextCreatedToken = new WindowToken.Builder(mWm, mClientToken,
+                TYPE_INPUT_METHOD_DIALOG)
+                .setDisplayContent(dualDisplayContent)
+                .setFromClientToken(true)
+                .build();
+        mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken,
+                TEST_UID, TYPE_INPUT_METHOD_DIALOG, null /* options */);
+
+        assertThat(mController.getContainer(mClientToken)).isEqualTo(windowContextCreatedToken);
+
+        // Remove WindowToken
+        windowContextCreatedToken.removeImmediately();
+
+        // Now context should listen to ImeContainer.
+        assertThat(mController.getContainer(mClientToken)).isEqualTo(imeContainer);
+    }
+
     private class TestWindowTokenClient extends IWindowToken.Stub {
         private Configuration mConfiguration;
         private int mDisplayId;
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 32c95f1..cf2c9c7 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,9 +16,14 @@
 
 package com.android.server;
 
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.INetd.IF_STATE_DOWN;
 import static android.net.INetd.IF_STATE_UP;
+import static android.net.IpSecManager.DIRECTION_FWD;
+import static android.net.IpSecManager.DIRECTION_IN;
+import static android.net.IpSecManager.DIRECTION_OUT;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
@@ -56,6 +61,7 @@
 import android.os.ParcelFileDescriptor;
 import android.system.Os;
 import android.test.mock.MockContext;
+import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
 
@@ -71,6 +77,7 @@
 import java.net.Socket;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Set;
 
 /** Unit tests for {@link IpSecService}. */
 @SmallTest
@@ -119,7 +126,18 @@
     AppOpsManager mMockAppOps = mock(AppOpsManager.class);
     ConnectivityManager mMockConnectivityMgr = mock(ConnectivityManager.class);
 
-    MockContext mMockContext = new MockContext() {
+    TestContext mTestContext = new TestContext();
+
+    private class TestContext extends MockContext {
+        private Set<String> mAllowedPermissions = new ArraySet<>(Arrays.asList(
+                android.Manifest.permission.MANAGE_IPSEC_TUNNELS,
+                android.Manifest.permission.NETWORK_STACK,
+                PERMISSION_MAINLINE_NETWORK_STACK));
+
+        private void setAllowedPermissions(String... permissions) {
+            mAllowedPermissions = new ArraySet<>(permissions);
+        }
+
         @Override
         public Object getSystemService(String name) {
             switch(name) {
@@ -147,20 +165,22 @@
 
         @Override
         public void enforceCallingOrSelfPermission(String permission, String message) {
-            if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
+            if (mAllowedPermissions.contains(permission)) {
                 return;
+            } else {
+                throw new SecurityException("Unavailable permission requested");
             }
-            throw new SecurityException("Unavailable permission requested");
         }
 
         @Override
         public int checkCallingOrSelfPermission(String permission) {
-            if (android.Manifest.permission.NETWORK_STACK.equals(permission)) {
+            if (mAllowedPermissions.contains(permission)) {
                 return PERMISSION_GRANTED;
+            } else {
+                return PERMISSION_DENIED;
             }
-            throw new UnsupportedOperationException();
         }
-    };
+    }
 
     INetd mMockNetd;
     PackageManager mMockPkgMgr;
@@ -194,7 +214,7 @@
         mMockNetd = mock(INetd.class);
         mMockPkgMgr = mock(PackageManager.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mTestContext, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -664,6 +684,21 @@
 
         assertNotNull(createTunnelResp);
         assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
+        for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT, DIRECTION_FWD}) {
+            for (int selAddrFamily : ADDRESS_FAMILIES) {
+                verify(mMockNetd).ipSecAddSecurityPolicy(
+                        eq(mUid),
+                        eq(selAddrFamily),
+                        eq(direction),
+                        anyString(),
+                        anyString(),
+                        eq(0),
+                        anyInt(), // iKey/oKey
+                        anyInt(), // mask
+                        eq(createTunnelResp.resourceId));
+            }
+        }
+
         return createTunnelResp;
     }
 
@@ -798,16 +833,51 @@
     }
 
     @Test
-    public void testApplyTunnelModeTransform() throws Exception {
-        verifyApplyTunnelModeTransformCommon(false);
+    public void testApplyTunnelModeTransformOutbound() throws Exception {
+        verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
     }
 
     @Test
-    public void testApplyTunnelModeTransformReleasedSpi() throws Exception {
-        verifyApplyTunnelModeTransformCommon(true);
+    public void testApplyTunnelModeTransformOutboundNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+        verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
     }
 
-    public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply) throws Exception {
+    @Test
+    public void testApplyTunnelModeTransformOutboundReleasedSpi() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_OUT);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformInbound() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformInboundNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformForward() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformForwardNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+
+        try {
+            verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
+            fail("Expected security exception due to use of forward policies without NETWORK_STACK"
+                     + " or MAINLINE_NETWORK_STACK permission");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply, int direction)
+            throws Exception {
         IpSecConfig ipSecConfig = new IpSecConfig();
         ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
         addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
@@ -825,17 +895,17 @@
         int transformResourceId = createTransformResp.resourceId;
         int tunnelResourceId = createTunnelResp.resourceId;
         mIpSecService.applyTunnelModeTransform(
-                tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE);
+                tunnelResourceId, direction, transformResourceId, BLESSED_PACKAGE);
 
         for (int selAddrFamily : ADDRESS_FAMILIES) {
             verify(mMockNetd)
                     .ipSecUpdateSecurityPolicy(
                             eq(mUid),
                             eq(selAddrFamily),
-                            eq(IpSecManager.DIRECTION_OUT),
+                            eq(direction),
                             anyString(),
                             anyString(),
-                            eq(TEST_SPI),
+                            eq(direction == DIRECTION_OUT ? TEST_SPI : 0),
                             anyInt(), // iKey/oKey
                             anyInt(), // mask
                             eq(tunnelResourceId));
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index eedaac4..39f7386 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -16,8 +16,11 @@
 
 package com.android.server.vcn;
 
+import static android.net.IpSecManager.DIRECTION_FWD;
 import static android.net.IpSecManager.DIRECTION_IN;
 import static android.net.IpSecManager.DIRECTION_OUT;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
@@ -54,6 +57,8 @@
 import android.net.ipsec.ike.exceptions.IkeException;
 import android.net.ipsec.ike.exceptions.IkeInternalException;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnGatewayConnectionConfig;
+import android.net.vcn.VcnGatewayConnectionConfigTest;
 import android.net.vcn.VcnManager.VcnErrorCode;
 
 import androidx.test.filters.SmallTest;
@@ -143,8 +148,9 @@
         assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
     }
 
-    @Test
-    public void testCreatedTransformsAreApplied() throws Exception {
+    private void verifyVcnTransformsApplied(
+            VcnGatewayConnection vcnGatewayConnection, boolean expectForwardTransform)
+            throws Exception {
         for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
             getChildSessionCallback().onIpSecTransformCreated(makeDummyIpSecTransform(), direction);
             mTestLooper.dispatchAll();
@@ -154,7 +160,40 @@
                             eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
         }
 
-        assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+        verify(mIpSecSvc, expectForwardTransform ? times(1) : never())
+                .applyTunnelModeTransform(
+                        eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(DIRECTION_FWD), anyInt(), any());
+
+        assertEquals(vcnGatewayConnection.mConnectedState, vcnGatewayConnection.getCurrentState());
+    }
+
+    @Test
+    public void testCreatedTransformsAreApplied() throws Exception {
+        verifyVcnTransformsApplied(mGatewayConnection, false /* expectForwardTransform */);
+    }
+
+    @Test
+    public void testCreatedTransformsAreAppliedWithDun() throws Exception {
+        VcnGatewayConnectionConfig gatewayConfig =
+                VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(
+                        NET_CAPABILITY_INTERNET, NET_CAPABILITY_DUN);
+        VcnGatewayConnection gatewayConnection =
+                new VcnGatewayConnection(
+                        mVcnContext,
+                        TEST_SUB_GRP,
+                        TEST_SUBSCRIPTION_SNAPSHOT,
+                        gatewayConfig,
+                        mGatewayStatusCallback,
+                        true /* isMobileDataEnabled */,
+                        mDeps);
+        gatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
+        final VcnIkeSession session =
+                gatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
+        gatewayConnection.setIkeSession(session);
+        gatewayConnection.transitionTo(gatewayConnection.mConnectedState);
+        mTestLooper.dispatchAll();
+
+        verifyVcnTransformsApplied(gatewayConnection, true /* expectForwardTransform */);
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index 284f1f8..1ecb4c9 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -220,7 +220,7 @@
     protected VcnChildSessionCallback getChildSessionCallback() {
         ArgumentCaptor<ChildSessionCallback> captor =
                 ArgumentCaptor.forClass(ChildSessionCallback.class);
-        verify(mDeps).newIkeSession(any(), any(), any(), any(), captor.capture());
+        verify(mDeps, atLeastOnce()).newIkeSession(any(), any(), any(), any(), captor.capture());
         return (VcnChildSessionCallback) captor.getValue();
     }