Merge "Fix ripple radius calculation" into sc-dev
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 0b24c0d..b5e3662 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -90,6 +90,7 @@
             @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
         try {
             mService.initialize(
+                    mPackageName,
                     mUserHandle,
                     /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
                     new IAppSearchResultCallback.Stub() {
@@ -685,7 +686,9 @@
         if (mIsMutated && !mIsClosed) {
             try {
                 mService.persistToDisk(
-                        mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
+                        mPackageName,
+                        mUserHandle,
+                        /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
                 mIsClosed = true;
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to close the AppSearchSession", e);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
index 247eb08..130e442 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
@@ -73,6 +73,7 @@
             @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
         try {
             mService.initialize(
+                    mPackageName,
                     mUserHandle,
                     /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
                     new IAppSearchResultCallback.Stub() {
@@ -187,7 +188,9 @@
         if (mIsMutated && !mIsClosed) {
             try {
                 mService.persistToDisk(
-                        mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
+                        mPackageName,
+                        mUserHandle,
+                        /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
                 mIsClosed = true;
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to close the GlobalSearchSession", e);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
index eb5d22e..6dfa01f 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
@@ -124,7 +124,8 @@
                             wrapCallback(executor, callback));
                 }
             } else {
-                mService.getNextPage(mNextPageToken, mUserHandle, wrapCallback(executor, callback));
+                mService.getNextPage(mPackageName, mNextPageToken, mUserHandle,
+                        wrapCallback(executor, callback));
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -135,7 +136,7 @@
     public void close() {
         if (!mIsClosed) {
             try {
-                mService.invalidateNextPageToken(mNextPageToken, mUserHandle);
+                mService.invalidateNextPageToken(mPackageName, mNextPageToken, mUserHandle);
                 mIsClosed = true;
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to close the SearchResults", e);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
index c639ef6..a2f545f 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
@@ -181,21 +181,30 @@
      * Fetches the next page of results of a previously executed query. Results can be empty if
      * next-page token is invalid or all pages have been returned.
      *
+     * @param packageName The name of the package to persist to disk for.
      * @param nextPageToken The token of pre-loaded results of previously executed query.
      * @param userHandle Handle of the calling user
      * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
      *                  operation.
      */
-    void getNextPage(in long nextPageToken, in UserHandle userHandle, in IAppSearchResultCallback callback);
+    void getNextPage(
+        in String packageName,
+        in long nextPageToken,
+        in UserHandle userHandle,
+        in IAppSearchResultCallback callback);
 
     /**
      * Invalidates the next-page token so that no more results of the related query can be returned.
      *
+     * @param packageName The name of the package to persist to disk for.
      * @param nextPageToken The token of pre-loaded results of previously executed query to be
      *                      Invalidated.
      * @param userHandle Handle of the calling user
      */
-    void invalidateNextPageToken(in long nextPageToken, in UserHandle userHandle);
+    void invalidateNextPageToken(
+        in String packageName,
+        in long nextPageToken,
+        in UserHandle userHandle);
 
     /**
     * Searches a document based on a given specifications.
@@ -336,20 +345,26 @@
     /**
      * Persists all update/delete requests to the disk.
      *
+     * @param packageName The name of the package to persist to disk for.
      * @param userHandle Handle of the calling user
      * @param binderCallStartTimeMillis start timestamp of binder call in Millis
      */
-    void persistToDisk(in UserHandle userHandle, in long binderCallStartTimeMillis);
+    void persistToDisk(
+        in String packageName,
+        in UserHandle userHandle,
+        in long binderCallStartTimeMillis);
 
     /**
      * Creates and initializes AppSearchImpl for the calling app.
      *
+     * @param packageName The name of the package to initialize for.
      * @param userHandle Handle of the calling user
      * @param binderCallStartTimeMillis start timestamp of binder call in Millis
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
      *     {@link AppSearchResult}&lt;{@link Void}&gt;.
      */
     void initialize(
+        in String packageName,
         in UserHandle userHandle,
         in long binderCallStartTimeMillis,
         in IAppSearchResultCallback callback);
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java
index 272e12d..d493a1c 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java
@@ -96,17 +96,6 @@
         return Collections.unmodifiableMap(mAll);
     }
 
-    /**
-     * Asserts that this {@link AppSearchBatchResult} has no failures.
-     *
-     * @hide
-     */
-    public void checkSuccess() {
-        if (!isSuccess()) {
-            throw new IllegalStateException("AppSearchBatchResult has failures: " + this);
-        }
-    }
-
     @Override
     @NonNull
     public String toString() {
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java
index c57cf2e..b1cb132 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java
@@ -239,6 +239,8 @@
             resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
         } else if (t instanceof IOException) {
             resultCode = AppSearchResult.RESULT_IO_ERROR;
+        } else if (t instanceof SecurityException) {
+            resultCode = AppSearchResult.RESULT_SECURITY_ERROR;
         } else {
             resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
         }
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 237e624..0ee5e65 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.app.appsearch.exceptions.IllegalSchemaException;
 import android.app.appsearch.util.BundleUtil;
+import android.app.appsearch.util.IndentingStringBuilder;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.util.ArraySet;
@@ -30,6 +31,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -67,8 +69,45 @@
     }
 
     @Override
+    @NonNull
     public String toString() {
-        return mBundle.toString();
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+        appendAppSearchSchemaString(stringBuilder);
+        return stringBuilder.toString();
+    }
+
+    /**
+     * Appends a debugging string for the {@link AppSearchSchema} instance to the given string
+     * builder.
+     *
+     * @param builder the builder to append to.
+     */
+    private void appendAppSearchSchemaString(@NonNull IndentingStringBuilder builder) {
+        Objects.requireNonNull(builder);
+
+        builder.append("{\n");
+        builder.increaseIndentLevel();
+        builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
+        builder.append("properties: [\n");
+
+        AppSearchSchema.PropertyConfig[] sortedProperties =
+                getProperties().toArray(new AppSearchSchema.PropertyConfig[0]);
+        Arrays.sort(sortedProperties, (o1, o2) -> o1.getName().compareTo(o2.getName()));
+
+        for (int i = 0; i < sortedProperties.length; i++) {
+            AppSearchSchema.PropertyConfig propertyConfig = sortedProperties[i];
+            builder.increaseIndentLevel();
+            propertyConfig.appendPropertyConfigString(builder);
+            if (i != sortedProperties.length - 1) {
+                builder.append(",\n");
+            }
+            builder.decreaseIndentLevel();
+        }
+
+        builder.append("\n");
+        builder.append("]\n");
+        builder.decreaseIndentLevel();
+        builder.append("}");
     }
 
     /** Returns the name of this schema type, e.g. Email. */
@@ -255,7 +294,68 @@
         @Override
         @NonNull
         public String toString() {
-            return mBundle.toString();
+            IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+            appendPropertyConfigString(stringBuilder);
+            return stringBuilder.toString();
+        }
+
+        /**
+         * Appends a debug string for the {@link AppSearchSchema.PropertyConfig} instance to the
+         * given string builder.
+         *
+         * @param builder the builder to append to.
+         */
+        void appendPropertyConfigString(@NonNull IndentingStringBuilder builder) {
+            Objects.requireNonNull(builder);
+
+            builder.append("{\n");
+            builder.increaseIndentLevel();
+            builder.append("name: \"").append(getName()).append("\",\n");
+
+            if (this instanceof AppSearchSchema.StringPropertyConfig) {
+                ((StringPropertyConfig) this).appendStringPropertyConfigFields(builder);
+            } else if (this instanceof AppSearchSchema.DocumentPropertyConfig) {
+                ((DocumentPropertyConfig) this).appendDocumentPropertyConfigFields(builder);
+            }
+
+            switch (getCardinality()) {
+                case AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED:
+                    builder.append("cardinality: CARDINALITY_REPEATED,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL:
+                    builder.append("cardinality: CARDINALITY_OPTIONAL,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED:
+                    builder.append("cardinality: CARDINALITY_REQUIRED,\n");
+                    break;
+                default:
+                    builder.append("cardinality: CARDINALITY_UNKNOWN,\n");
+            }
+
+            switch (getDataType()) {
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_STRING:
+                    builder.append("dataType: DATA_TYPE_STRING,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_LONG:
+                    builder.append("dataType: DATA_TYPE_LONG,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_DOUBLE:
+                    builder.append("dataType: DATA_TYPE_DOUBLE,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN:
+                    builder.append("dataType: DATA_TYPE_BOOLEAN,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES:
+                    builder.append("dataType: DATA_TYPE_BYTES,\n");
+                    break;
+                case AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT:
+                    builder.append("dataType: DATA_TYPE_DOCUMENT,\n");
+                    break;
+                default:
+                    builder.append("dataType: DATA_TYPE_UNKNOWN,\n");
+            }
+            builder.decreaseIndentLevel();
+            builder.append("}");
         }
 
         /** Returns the name of this property. */
@@ -506,6 +606,41 @@
                 return new StringPropertyConfig(bundle);
             }
         }
+
+        /**
+         * Appends a debug string for the {@link StringPropertyConfig} instance to the given string
+         * builder.
+         *
+         * <p>This appends fields specific to a {@link StringPropertyConfig} instance.
+         *
+         * @param builder the builder to append to.
+         */
+        void appendStringPropertyConfigFields(@NonNull IndentingStringBuilder builder) {
+            switch (getIndexingType()) {
+                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE:
+                    builder.append("indexingType: INDEXING_TYPE_NONE,\n");
+                    break;
+                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS:
+                    builder.append("indexingType: INDEXING_TYPE_EXACT_TERMS,\n");
+                    break;
+                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES:
+                    builder.append("indexingType: INDEXING_TYPE_PREFIXES,\n");
+                    break;
+                default:
+                    builder.append("indexingType: INDEXING_TYPE_UNKNOWN,\n");
+            }
+
+            switch (getTokenizerType()) {
+                case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE:
+                    builder.append("tokenizerType: TOKENIZER_TYPE_NONE,\n");
+                    break;
+                case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN:
+                    builder.append("tokenizerType: TOKENIZER_TYPE_PLAIN,\n");
+                    break;
+                default:
+                    builder.append("tokenizerType: TOKENIZER_TYPE_UNKNOWN,\n");
+            }
+        }
     }
 
     /**
@@ -858,5 +993,21 @@
                 return new DocumentPropertyConfig(bundle);
             }
         }
+
+        /**
+         * Appends a debug string for the {@link DocumentPropertyConfig} instance to the given
+         * string builder.
+         *
+         * <p>This appends fields specific to a {@link DocumentPropertyConfig} instance.
+         *
+         * @param builder the builder to append to.
+         */
+        void appendDocumentPropertyConfigFields(@NonNull IndentingStringBuilder builder) {
+            builder.append("shouldIndexNestedProperties: ")
+                    .append(shouldIndexNestedProperties())
+                    .append(",\n");
+
+            builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
+        }
     }
 }
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 bcd341e..c905f95 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.appsearch.util.BundleUtil;
+import android.app.appsearch.util.IndentingStringBuilder;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Parcelable;
@@ -50,9 +51,6 @@
 public class GenericDocument {
     private static final String TAG = "AppSearchGenericDocumen";
 
-    /** The maximum number of elements in a repeatable field. */
-    private static final int MAX_REPEATED_PROPERTY_LENGTH = 100;
-
     /** The maximum {@link String#length} of a {@link String} field. */
     private static final int MAX_STRING_LENGTH = 20_000;
 
@@ -861,6 +859,7 @@
      *
      * @hide
      */
+    // TODO(b/171882200): Expose this API in Android T
     @NonNull
     public GenericDocument.Builder<GenericDocument.Builder<?>> toBuilder() {
         Bundle clonedBundle = BundleUtil.deepCopy(mBundle);
@@ -890,121 +889,101 @@
     @Override
     @NonNull
     public String toString() {
-        StringBuilder stringBuilder = new StringBuilder();
-        appendGenericDocumentString(this, /*indentLevel=*/ 0, stringBuilder);
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+        appendGenericDocumentString(stringBuilder);
         return stringBuilder.toString();
     }
 
-    private static void appendGenericDocumentString(
-            @NonNull GenericDocument document, int indentLevel, @NonNull StringBuilder builder) {
-        Objects.requireNonNull(document);
+    /**
+     * Appends a debug string for the {@link GenericDocument} instance to the given string builder.
+     *
+     * @param builder the builder to append to.
+     */
+    void appendGenericDocumentString(@NonNull IndentingStringBuilder builder) {
         Objects.requireNonNull(builder);
 
-        builder.append(getIndent(indentLevel)).append("{\n");
+        builder.append("{\n");
+        builder.increaseIndentLevel();
 
-        String indent1 = getIndent(indentLevel + 1);
-
-        builder.append(indent1)
-                .append("namespace: \"")
-                .append(document.getNamespace())
-                .append("\",\n");
-
-        builder.append(indent1).append("id: \"").append(document.getId()).append("\",\n");
-
-        builder.append(indent1).append("score: ").append(document.getScore()).append(",\n");
-
-        builder.append(indent1)
-                .append("schemaType: \"")
-                .append(document.getSchemaType())
-                .append("\",\n");
-
-        builder.append(indent1)
-                .append("creationTimestampMillis: ")
-                .append(document.getCreationTimestampMillis())
+        builder.append("namespace: \"").append(getNamespace()).append("\",\n");
+        builder.append("id: \"").append(getId()).append("\",\n");
+        builder.append("score: ").append(getScore()).append(",\n");
+        builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
+        builder.append("creationTimestampMillis: ")
+                .append(getCreationTimestampMillis())
                 .append(",\n");
+        builder.append("timeToLiveMillis: ").append(getTtlMillis()).append(",\n");
 
-        builder.append(indent1)
-                .append("timeToLiveMillis: ")
-                .append(document.getTtlMillis())
-                .append(",\n");
+        builder.append("properties: {\n");
 
-        builder.append(indent1).append("properties: {\n");
-
-        String[] sortedProperties = document.getPropertyNames().toArray(new String[0]);
+        String[] sortedProperties = getPropertyNames().toArray(new String[0]);
         Arrays.sort(sortedProperties);
 
         for (int i = 0; i < sortedProperties.length; i++) {
-            Object property = document.getProperty(sortedProperties[i]);
-            builder.append(getIndent(indentLevel + 2))
-                    .append("\"")
-                    .append(sortedProperties[i])
-                    .append("\"")
-                    .append(": ");
-            appendPropertyString(property, indentLevel + 2, builder);
+            Object property = getProperty(sortedProperties[i]);
+            builder.increaseIndentLevel();
+            appendPropertyString(sortedProperties[i], property, builder);
             if (i != sortedProperties.length - 1) {
                 builder.append(",\n");
             }
+            builder.decreaseIndentLevel();
         }
 
         builder.append("\n");
-        builder.append(indent1).append("}");
+        builder.append("}");
 
+        builder.decreaseIndentLevel();
         builder.append("\n");
-        builder.append(getIndent(indentLevel)).append("}");
+        builder.append("}");
     }
 
     /**
-     * Appends a string for the given property to the given builder.
+     * Appends a debug string for the given document property to the given string builder.
      *
+     * @param propertyName name of property to create string for.
      * @param property property object to create string for.
-     * @param indentLevel base indent level for property.
      * @param builder the builder to append to.
      */
-    private static void appendPropertyString(
-            @NonNull Object property, int indentLevel, @NonNull StringBuilder builder) {
+    private void appendPropertyString(
+            @NonNull String propertyName,
+            @NonNull Object property,
+            @NonNull IndentingStringBuilder builder) {
+        Objects.requireNonNull(propertyName);
         Objects.requireNonNull(property);
         Objects.requireNonNull(builder);
 
-        builder.append("[");
+        builder.append("\"").append(propertyName).append("\": [");
         if (property instanceof GenericDocument[]) {
             GenericDocument[] documentValues = (GenericDocument[]) property;
             for (int i = 0; i < documentValues.length; ++i) {
                 builder.append("\n");
-                appendGenericDocumentString(documentValues[i], indentLevel + 1, builder);
+                builder.increaseIndentLevel();
+                documentValues[i].appendGenericDocumentString(builder);
                 if (i != documentValues.length - 1) {
-                    builder.append(", ");
+                    builder.append(",");
                 }
                 builder.append("\n");
+                builder.decreaseIndentLevel();
             }
-            builder.append(getIndent(indentLevel));
+            builder.append("]");
         } else {
             int propertyArrLength = Array.getLength(property);
             for (int i = 0; i < propertyArrLength; i++) {
                 Object propertyElement = Array.get(property, i);
                 if (propertyElement instanceof String) {
-                    builder.append("\"").append(propertyElement).append("\"");
+                    builder.append("\"").append((String) propertyElement).append("\"");
                 } else if (propertyElement instanceof byte[]) {
                     builder.append(Arrays.toString((byte[]) propertyElement));
                 } else {
-                    builder.append(propertyElement);
+                    builder.append(propertyElement.toString());
                 }
                 if (i != propertyArrLength - 1) {
                     builder.append(", ");
+                } else {
+                    builder.append("]");
                 }
             }
         }
-
-        builder.append("]");
-    }
-
-    /** Appends a string for given indent level to the given builder. */
-    @NonNull
-    private static String getIndent(int indentLevel) {
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < indentLevel; ++i) {
-            builder.append("  ");
-        }
-        return builder.toString();
     }
 
     /**
@@ -1187,8 +1166,8 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@code String} values of the property.
-         * @throws IllegalArgumentException if no values are provided, if provided values exceed
-         *     maximum repeated property length, or if a passed in {@code String} is {@code null}.
+         * @throws IllegalArgumentException if no values are provided, or if a passed in {@code
+         *     String} is {@code null}.
          */
         @NonNull
         public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
@@ -1206,7 +1185,6 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@code boolean} values of the property.
-         * @throws IllegalArgumentException if values exceed maximum repeated property length.
          */
         @NonNull
         public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
@@ -1223,7 +1201,6 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@code long} values of the property.
-         * @throws IllegalArgumentException if values exceed maximum repeated property length.
          */
         @NonNull
         public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
@@ -1240,7 +1217,6 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@code double} values of the property.
-         * @throws IllegalArgumentException if values exceed maximum repeated property length.
          */
         @NonNull
         public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
@@ -1257,8 +1233,8 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@code byte[]} of the property.
-         * @throws IllegalArgumentException if no values are provided, if provided values exceed
-         *     maximum repeated property length, or if a passed in {@code byte[]} is {@code null}.
+         * @throws IllegalArgumentException if no values are provided, or if a passed in {@code
+         *     byte[]} is {@code null}.
          */
         @NonNull
         public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
@@ -1276,8 +1252,7 @@
          * @param name the name associated with the {@code values}. Must match the name for this
          *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
          * @param values the {@link GenericDocument} values of the property.
-         * @throws IllegalArgumentException if no values are provided, if provided values exceed if
-         *     provided values exceed maximum repeated property length, or if a passed in {@link
+         * @throws IllegalArgumentException if no values are provided, or if a passed in {@link
          *     GenericDocument} is {@code null}.
          */
         @NonNull
@@ -1308,7 +1283,6 @@
 
         private void putInPropertyBundle(@NonNull String name, @NonNull String[] values)
                 throws IllegalArgumentException {
-            validateRepeatedPropertyLength(name, values.length);
             for (int i = 0; i < values.length; i++) {
                 if (values[i] == null) {
                     throw new IllegalArgumentException("The String at " + i + " is null.");
@@ -1327,17 +1301,14 @@
         }
 
         private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) {
-            validateRepeatedPropertyLength(name, values.length);
             mProperties.putBooleanArray(name, values);
         }
 
         private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) {
-            validateRepeatedPropertyLength(name, values.length);
             mProperties.putDoubleArray(name, values);
         }
 
         private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) {
-            validateRepeatedPropertyLength(name, values.length);
             mProperties.putLongArray(name, values);
         }
 
@@ -1348,7 +1319,6 @@
          * into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
          */
         private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) {
-            validateRepeatedPropertyLength(name, values.length);
             ArrayList<Bundle> bundles = new ArrayList<>(values.length);
             for (int i = 0; i < values.length; i++) {
                 if (values[i] == null) {
@@ -1362,7 +1332,6 @@
         }
 
         private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) {
-            validateRepeatedPropertyLength(name, values.length);
             Parcelable[] documentBundles = new Parcelable[values.length];
             for (int i = 0; i < values.length; i++) {
                 if (values[i] == null) {
@@ -1373,18 +1342,6 @@
             mProperties.putParcelableArray(name, documentBundles);
         }
 
-        private static void validateRepeatedPropertyLength(@NonNull String name, int length) {
-            if (length > MAX_REPEATED_PROPERTY_LENGTH) {
-                throw new IllegalArgumentException(
-                        "Repeated property \""
-                                + name
-                                + "\" has length "
-                                + length
-                                + ", which exceeds the limit of "
-                                + MAX_REPEATED_PROPERTY_LENGTH);
-            }
-        }
-
         /** Builds the {@link GenericDocument} object. */
         @NonNull
         public GenericDocument build() {
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 0af3e7a..b72ca9a 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -169,13 +169,14 @@
 
     /** Builder for {@link SetSchemaRequest} objects. */
     public static final class Builder {
+        private static final int DEFAULT_VERSION = 1;
         private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>();
         private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
         private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
                 new ArrayMap<>();
         private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
         private boolean mForceOverride = false;
-        private int mVersion = 1;
+        private int mVersion = DEFAULT_VERSION;
         private boolean mBuilt = false;
 
         /**
@@ -384,6 +385,9 @@
          * <p>The version number can stay the same, increase, or decrease relative to the current
          * version number that is already stored in the {@link AppSearchSession} database.
          *
+         * <p>The version of an empty database will always be 0. You cannot set version to the
+         * {@link SetSchemaRequest}, if it doesn't contains any {@link AppSearchSchema}.
+         *
          * @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.
@@ -423,7 +427,10 @@
                 throw new IllegalArgumentException(
                         "Schema types " + referencedSchemas + " referenced, but were not added.");
             }
-
+            if (mSchemas.isEmpty() && mVersion != DEFAULT_VERSION) {
+                throw new IllegalArgumentException(
+                        "Cannot set version to the request if schema is empty.");
+            }
             mBuilt = true;
             return new SetSchemaRequest(
                     mSchemas,
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java
new file mode 100644
index 0000000..b494c3c
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java
@@ -0,0 +1,126 @@
+/*
+ * 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.util;
+
+import android.annotation.NonNull;
+
+/**
+ * Utility for building indented strings.
+ *
+ * <p>This is a wrapper for {@link StringBuilder} for appending strings with indentation. The
+ * indentation level can be increased by calling {@link #increaseIndentLevel()} and decreased by
+ * calling {@link #decreaseIndentLevel()}.
+ *
+ * <p>Indentation is applied after each newline character for the given indent level.
+ *
+ * @hide
+ */
+public class IndentingStringBuilder {
+    private final StringBuilder mStringBuilder = new StringBuilder();
+
+    // Indicates whether next non-newline character should have an indent applied before it.
+    private boolean mIndentNext = false;
+    private int mIndentLevel = 0;
+
+    /** Increases the indent level by one for appended strings. */
+    @NonNull
+    public IndentingStringBuilder increaseIndentLevel() {
+        mIndentLevel++;
+        return this;
+    }
+
+    /** Decreases the indent level by one for appended strings. */
+    @NonNull
+    public IndentingStringBuilder decreaseIndentLevel() throws IllegalStateException {
+        if (mIndentLevel == 0) {
+            throw new IllegalStateException("Cannot set indent level below 0.");
+        }
+        mIndentLevel--;
+        return this;
+    }
+
+    /**
+     * Appends provided {@code String} at the current indentation level.
+     *
+     * <p>Indentation is applied after each newline character.
+     */
+    @NonNull
+    public IndentingStringBuilder append(@NonNull String str) {
+        applyIndentToString(str);
+        return this;
+    }
+
+    /**
+     * Appends provided {@code Object}, represented as a {@code String}, at the current indentation
+     * level.
+     *
+     * <p>Indentation is applied after each newline character.
+     */
+    @NonNull
+    public IndentingStringBuilder append(@NonNull Object obj) {
+        applyIndentToString(obj.toString());
+        return this;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return mStringBuilder.toString();
+    }
+
+    /** Adds indent string to the {@link StringBuilder} instance for current indent level. */
+    private void applyIndent() {
+        for (int i = 0; i < mIndentLevel; i++) {
+            mStringBuilder.append("  ");
+        }
+    }
+
+    /**
+     * Applies indent, for current indent level, after each newline character.
+     *
+     * <p>Consecutive newline characters are not indented.
+     */
+    private void applyIndentToString(@NonNull String str) {
+        int index = str.indexOf("\n");
+        if (index == 0) {
+            // String begins with new line character: append newline and slide past newline.
+            mStringBuilder.append("\n");
+            mIndentNext = true;
+            if (str.length() > 1) {
+                applyIndentToString(str.substring(index + 1));
+            }
+        } else if (index >= 1) {
+            // String contains new line character: divide string between newline, append new line,
+            // and recurse on each string.
+            String beforeIndentString = str.substring(0, index);
+            applyIndentToString(beforeIndentString);
+            mStringBuilder.append("\n");
+            mIndentNext = true;
+            if (str.length() > index + 1) {
+                String afterIndentString = str.substring(index + 1);
+                applyIndentToString(afterIndentString);
+            }
+        } else {
+            // String does not contain newline character: append string.
+            if (mIndentNext) {
+                applyIndent();
+                mIndentNext = false;
+            }
+            mStringBuilder.append(str);
+        }
+    }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index ac584fe..481d51e 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -60,8 +60,8 @@
 import com.android.server.LocalManagerRegistry;
 import com.android.server.SystemService;
 import com.android.server.appsearch.external.localstorage.stats.CallStats;
+import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
 import com.android.server.appsearch.util.PackageUtil;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
 import com.android.server.usage.StorageStatsManagerLocal;
 import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
 
@@ -220,9 +220,10 @@
             }
             // Only clear the package's data if AppSearch exists for this user.
             if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
+                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
                 AppSearchUserInstance instance =
                         mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
                 //TODO(b/145759910) clear visibility setting for package.
                 instance.getAppSearchImpl().clearPackageData(packageName);
                 instance.getLogger().removeCachedUidForPackage(packageName);
@@ -243,11 +244,11 @@
             try {
                 // Only clear the package's data if AppSearch exists for this user.
                 if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
+                    Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                    mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                    List<PackageInfo> installedPackageInfos = mContext
-                            .createContextAsUser(userHandle, /*flags=*/0)
+                                    userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+                    List<PackageInfo> installedPackageInfos = userContext
                             .getPackageManager()
                             .getInstalledPackages(/*flags=*/0);
                     Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
@@ -327,8 +328,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
                     for (int i = 0; i < schemaBundles.size(); i++) {
                         schemas.add(new AppSearchSchema(schemaBundles.get(i)));
@@ -401,8 +404,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     GetSchemaResponse response =
@@ -431,8 +436,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     List<String> namespaces =
@@ -468,8 +475,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchBatchResult.Builder<String, Void> resultBuilder =
                             new AppSearchBatchResult.Builder<>();
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -548,8 +557,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
                             new AppSearchBatchResult.Builder<>();
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -627,8 +638,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
                             packageName,
@@ -691,8 +704,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
 
                     boolean callerHasSystemAccess =
@@ -738,9 +753,11 @@
 
         @Override
         public void getNextPage(
+                @NonNull String packageName,
                 long nextPageToken,
                 @NonNull UserHandle userHandle,
                 @NonNull IAppSearchResultCallback callback) {
+            Objects.requireNonNull(packageName);
             Objects.requireNonNull(userHandle);
             Objects.requireNonNull(callback);
 
@@ -750,7 +767,10 @@
             // opened it
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     SearchResultPage searchResultPage =
@@ -765,14 +785,19 @@
         }
 
         @Override
-        public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
+        public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken,
+                @NonNull UserHandle userHandle) {
+            Objects.requireNonNull(packageName);
             Objects.requireNonNull(userHandle);
 
             int callingUid = Binder.getCallingUid();
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
@@ -803,7 +828,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
+                    verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     // we don't need to append the file. The file is always brand new.
@@ -849,7 +877,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
+                    verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
 
@@ -908,8 +939,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
 
@@ -957,8 +990,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchBatchResult.Builder<String, Void> resultBuilder =
                             new AppSearchBatchResult.Builder<>();
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
@@ -1039,8 +1074,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     instance.getAppSearchImpl().removeByQuery(
                             packageName,
@@ -1095,8 +1132,10 @@
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
             EXECUTOR.execute(() -> {
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(callingUser, callingUid, packageName);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     AppSearchUserInstance instance =
                             mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     StorageInfo storageInfo = instance.getAppSearchImpl()
@@ -1112,8 +1151,10 @@
 
         @Override
         public void persistToDisk(
+                @NonNull String packageName,
                 @NonNull UserHandle userHandle,
                 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
+            Objects.requireNonNull(packageName);
             Objects.requireNonNull(userHandle);
 
             long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
@@ -1125,7 +1166,10 @@
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
                     instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
                     ++operationSuccessCount;
@@ -1157,24 +1201,30 @@
 
         @Override
         public void initialize(
+                @NonNull String packageName,
                 @NonNull UserHandle userHandle,
                 @ElapsedRealtimeLong long binderCallStartTimeMillis,
                 @NonNull IAppSearchResultCallback callback) {
+            Objects.requireNonNull(packageName);
             Objects.requireNonNull(userHandle);
             Objects.requireNonNull(callback);
 
             long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
             int callingUid = Binder.getCallingUid();
             UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
+
             EXECUTOR.execute(() -> {
                 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
                 AppSearchUserInstance instance = null;
                 int operationSuccessCount = 0;
                 int operationFailureCount = 0;
                 try {
+                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
                     verifyUserUnlocked(callingUser);
+                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
+                    verifyNotInstantApp(userContext, packageName);
                     instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                            mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
+                            userContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
                     ++operationSuccessCount;
                     invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
                 } catch (Throwable t) {
@@ -1204,14 +1254,15 @@
         }
 
         private void verifyCallingPackage(
+                @NonNull Context userContext,
                 @NonNull UserHandle actualCallingUser,
                 int actualCallingUid,
                 @NonNull String claimedCallingPackage) {
             Objects.requireNonNull(actualCallingUser);
             Objects.requireNonNull(claimedCallingPackage);
 
-            int claimedCallingUid = PackageUtil.getPackageUidAsUser(
-                    mContext, claimedCallingPackage, actualCallingUser);
+            int claimedCallingUid = PackageUtil.getPackageUid(
+                    userContext, claimedCallingPackage);
             if (claimedCallingUid == INVALID_UID) {
                 throw new SecurityException(
                         "Specified calling package [" + claimedCallingPackage + "] not found");
@@ -1317,6 +1368,21 @@
                         + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
     }
 
+    /**
+     * Helper for ensuring instant apps can't make calls to AppSearch.
+     *
+     * @param userContext Context of the user making the call.
+     * @param packageName Package name of the caller.
+     * @throws SecurityException if the caller is an instant app.
+     */
+    private void verifyNotInstantApp(@NonNull Context userContext, @NonNull String packageName) {
+        PackageManager callingPackageManager = userContext.getPackageManager();
+        if (callingPackageManager.isInstantApp(packageName)) {
+            throw new SecurityException("Caller not allowed to create AppSearch session"
+                    + "; userHandle=" + userContext.getUser() + ", callingPackage=" + packageName);
+        }
+    }
+
     // TODO(b/179160886): Cache the previous storage stats.
     private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
         @Override
@@ -1331,9 +1397,10 @@
 
             try {
                 verifyUserUnlocked(userHandle);
+                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
                 AppSearchUserInstance instance =
                         mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
                 stats.dataSize += instance.getAppSearchImpl()
                         .getStorageInfoForPackage(packageName).getSizeBytes();
             } catch (Throwable t) {
@@ -1359,9 +1426,10 @@
                 if (packagesForUid == null) {
                     return;
                 }
+                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
                 AppSearchUserInstance instance =
                         mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
                 for (int i = 0; i < packagesForUid.length; i++) {
                     stats.dataSize += instance.getAppSearchImpl()
                             .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
@@ -1387,9 +1455,10 @@
                 if (packagesForUser == null) {
                     return;
                 }
+                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
                 AppSearchUserInstance instance =
                         mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
+                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
                 for (int i = 0; i < packagesForUser.size(); i++) {
                     String packageName = packagesForUser.get(i).packageName;
                     stats.dataSize += instance.getAppSearchImpl()
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
index 7e743ed..56e2af5 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
@@ -19,7 +19,7 @@
 
 import com.android.server.appsearch.external.localstorage.AppSearchImpl;
 import com.android.server.appsearch.stats.PlatformLogger;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
 
 import java.util.Objects;
 
@@ -30,12 +30,12 @@
 public final class AppSearchUserInstance {
     private final PlatformLogger mLogger;
     private final AppSearchImpl mAppSearchImpl;
-    private final VisibilityStore mVisibilityStore;
+    private final VisibilityStoreImpl mVisibilityStore;
 
     AppSearchUserInstance(
             @NonNull PlatformLogger logger,
             @NonNull AppSearchImpl appSearchImpl,
-            @NonNull VisibilityStore visibilityStore) {
+            @NonNull VisibilityStoreImpl visibilityStore) {
         mLogger = Objects.requireNonNull(logger);
         mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
         mVisibilityStore = Objects.requireNonNull(visibilityStore);
@@ -52,7 +52,7 @@
     }
 
     @NonNull
-    public VisibilityStore getVisibilityStore() {
+    public VisibilityStoreImpl getVisibilityStore() {
         return mVisibilityStore;
     }
 }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
index cedc364..e067d4b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
@@ -30,7 +30,7 @@
 import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
 import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
 import com.android.server.appsearch.stats.PlatformLogger;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
 
 import java.io.File;
 import java.util.Map;
@@ -89,25 +89,24 @@
      * <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and
      * one will be created.
      *
-     * @param context The context
+     * @param userContext Context of the user calling AppSearch
      * @param userHandle The multi-user handle of the device user calling AppSearch
      * @param config Flag manager for AppSearch
      * @return An initialized {@link AppSearchUserInstance} for this user
      */
     @NonNull
     public AppSearchUserInstance getOrCreateUserInstance(
-            @NonNull Context context,
+            @NonNull Context userContext,
             @NonNull UserHandle userHandle,
             @NonNull AppSearchConfig config)
             throws AppSearchException {
-        Objects.requireNonNull(context);
+        Objects.requireNonNull(userContext);
         Objects.requireNonNull(userHandle);
         Objects.requireNonNull(config);
 
         synchronized (mInstancesLocked) {
             AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
             if (instance == null) {
-                Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0);
                 instance = createUserInstance(userContext, userHandle, config);
                 mInstancesLocked.put(userHandle, instance);
             }
@@ -169,7 +168,7 @@
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
 
         // Initialize the classes that make up AppSearchUserInstance
-        PlatformLogger logger = new PlatformLogger(userContext, userHandle, config);
+        PlatformLogger logger = new PlatformLogger(userContext, config);
 
         File appSearchDir = getAppSearchDir(userHandle);
         File icingDir = new File(appSearchDir, "icing");
@@ -178,7 +177,8 @@
                 AppSearchImpl.create(icingDir, initStatsBuilder, new FrameworkOptimizeStrategy());
 
         long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
-        VisibilityStore visibilityStore = VisibilityStore.create(appSearchImpl, userContext);
+        VisibilityStoreImpl visibilityStore =
+                VisibilityStoreImpl.create(appSearchImpl, userContext);
         long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
 
         initStatsBuilder
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 4ad1c8c..9dee179 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -58,7 +58,7 @@
 import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
 import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
 import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
 
 import com.google.android.icing.IcingSearchEngine;
 import com.google.android.icing.proto.DeleteByQueryResultProto;
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java
new file mode 100644
index 0000000..fb89250
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java
@@ -0,0 +1,72 @@
+/*
+ * 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.visibilitystore;
+
+import android.annotation.NonNull;
+import android.app.appsearch.PackageIdentifier;
+import android.app.appsearch.exceptions.AppSearchException;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An interface for classes that store and validate document visibility data.
+ *
+ * @hide
+ */
+public interface VisibilityStore {
+    /**
+     * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
+     * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
+     */
+    String PACKAGE_NAME = "VS#Pkg";
+
+    @VisibleForTesting String DATABASE_NAME = "VS#Db";
+
+    /**
+     * Sets visibility settings for the given database. Any previous visibility settings will be
+     * overwritten.
+     *
+     * @param packageName Package of app that owns the schemas.
+     * @param databaseName Database that owns the schemas.
+     * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from
+     *     platform surfaces.
+     * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
+     *     have access to the schema.
+     * @throws AppSearchException on AppSearchImpl error.
+     */
+    void setVisibility(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull Set<String> schemasNotDisplayedBySystem,
+            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
+            throws AppSearchException;
+
+    /**
+     * Checks whether the given package has access to system-surfaceable schemas.
+     *
+     * @param callerUid UID of the app that wants to see the data.
+     */
+    boolean isSchemaSearchableByCaller(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull String prefixedSchema,
+            int callerUid,
+            boolean callerHasSystemAccess);
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
index 31fead5e..322bd11 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.os.Process;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -55,11 +54,8 @@
 public final class PlatformLogger implements AppSearchLogger {
     private static final String TAG = "AppSearchPlatformLogger";
 
-    // Context of the system service.
-    private final Context mContext;
-
-    // User we're logging for.
-    private final UserHandle mUserHandle;
+    // Context of the user we're logging for.
+    private final Context mUserContext;
 
     // Manager holding the configuration flags
     private final AppSearchConfig mConfig;
@@ -120,10 +116,9 @@
      * Westworld constructor
      */
     public PlatformLogger(
-            @NonNull Context context, @NonNull UserHandle userHandle,
+            @NonNull Context userContext,
             @NonNull AppSearchConfig config) {
-        mContext = Objects.requireNonNull(context);
-        mUserHandle = Objects.requireNonNull(userHandle);
+        mUserContext = Objects.requireNonNull(userContext);
         mConfig = Objects.requireNonNull(config);
     }
 
@@ -451,7 +446,7 @@
     private int getPackageUidAsUserLocked(@NonNull String packageName) {
         Integer packageUid = mPackageUidCacheLocked.get(packageName);
         if (packageUid == null) {
-            packageUid = PackageUtil.getPackageUidAsUser(mContext, packageName, mUserHandle);
+            packageUid = PackageUtil.getPackageUid(mUserContext, packageName);
             if (packageUid != Process.INVALID_UID) {
                 mPackageUidCacheLocked.put(packageName, packageUid);
             }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java b/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java
index 53a1bed..714ffb6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Process;
-import android.os.UserHandle;
 
 /**
  * Utilities for interacting with {@link android.content.pm.PackageManager},
@@ -32,16 +31,6 @@
     private PackageUtil() {}
 
     /**
-     * Finds the UID of the {@code packageName}. Returns {@link Process#INVALID_UID} if unable to
-     * find the UID.
-     */
-    public static int getPackageUidAsUser(
-            @NonNull Context context, @NonNull String packageName, @NonNull UserHandle user) {
-        Context userContext = context.createContextAsUser(user, /*flags=*/ 0);
-        return getPackageUid(userContext, packageName);
-    }
-
-    /**
      * Finds the UID of the {@code packageName} in the given {@code context}. Returns
      * {@link Process#INVALID_UID} if unable to find the UID.
      */
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java
similarity index 88%
rename from apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
rename to apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java
index a096aef..ce142d6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java
@@ -30,9 +30,9 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.appsearch.external.localstorage.AppSearchImpl;
 import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
+import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
 import com.android.server.appsearch.util.PackageUtil;
 
 import com.google.android.icing.proto.PersistType;
@@ -60,23 +60,12 @@
  * <p>This class doesn't handle any locking itself. Its callers should handle the locking at a
  * higher level.
  *
- * <p>NOTE: This class holds an instance of AppSearchImpl and AppSearchImpl holds an instance of
- * this class. Take care to not cause any circular dependencies.
- *
  * @hide
  */
-public class VisibilityStore {
+public class VisibilityStoreImpl implements VisibilityStore {
     /** Version for the visibility schema */
     private static final int SCHEMA_VERSION = 0;
 
-    /**
-     * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
-     * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
-     */
-    public static final String PACKAGE_NAME = "VS#Pkg";
-
-    @VisibleForTesting public static final String DATABASE_NAME = "VS#Db";
-
     /** Namespace of documents that contain visibility settings */
     private static final String NAMESPACE = "";
 
@@ -101,13 +90,13 @@
      * @param userContext Context of the user that the call is being made as
      */
     @NonNull
-    public static VisibilityStore create(
+    public static VisibilityStoreImpl create(
             @NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
             throws AppSearchException {
-        return new VisibilityStore(appSearchImpl, userContext);
+        return new VisibilityStoreImpl(appSearchImpl, userContext);
     }
 
-    private VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
+    private VisibilityStoreImpl(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
             throws AppSearchException {
         mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
         mUserContext = Objects.requireNonNull(userContext);
@@ -207,18 +196,7 @@
         }
     }
 
-    /**
-     * Sets visibility settings for the given database. Any previous visibility settings will be
-     * overwritten.
-     *
-     * @param packageName Package of app that owns the schemas.
-     * @param databaseName Database that owns the schemas.
-     * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from the
-     *     platform.
-     * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
-     *     have access to the schema.
-     * @throws AppSearchException on AppSearchImpl error.
-     */
+    @Override
     public void setVisibility(
             @NonNull String packageName,
             @NonNull String databaseName,
@@ -282,17 +260,7 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    /**
-     * Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}.
-     *
-     * @param packageName Package that owns the schema.
-     * @param databaseName Database within the package that owns the schema.
-     * @param prefixedSchema Prefixed schema type the caller is trying to access.
-     * @param callerUid UID of the client making the globalQuery call.
-     * @param callerHasSystemAccess Whether the caller has been identified as having
-     *                              access to schemas marked system surfaceable by {@link
-     *                              #doesCallerHaveSystemAccess}.
-     */
+    @Override
     public boolean isSchemaSearchableByCaller(
             @NonNull String packageName,
             @NonNull String databaseName,
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 9859f20..6555107 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-04351b43fbbf9d59ffeae41903322023931c84f2
+c7387d9b58726a23a0608a9365fb3a1b57b7b8a1
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 0e9efbc..ac20187 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -442,6 +442,7 @@
     private long mNextIdlePendingDelay;
     private long mNextIdleDelay;
     private long mNextLightIdleDelay;
+    private long mNextLightIdleDelayFlex;
     private long mNextLightAlarmTime;
     private long mNextSensingTimeoutAlarmTime;
 
@@ -886,16 +887,20 @@
      */
     public final class Constants implements DeviceConfig.OnPropertiesChangedListener {
         // Key names stored in the settings value.
-        private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
-                = "light_after_inactive_to";
+        private static final String KEY_FLEX_TIME_SHORT = "flex_time_short";
+        private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
+                "light_after_inactive_to";
         private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
         private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
+        private static final String KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX =
+                "light_idle_to_initial_flex";
+        private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX = "light_max_idle_to_flex";
         private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
         private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
-        private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
-                = "light_idle_maintenance_min_budget";
-        private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
-                = "light_idle_maintenance_max_budget";
+        private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET =
+                "light_idle_maintenance_min_budget";
+        private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET =
+                "light_idle_maintenance_max_budget";
         private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
         private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
         private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
@@ -903,6 +908,7 @@
         private static final String KEY_LOCATING_TIMEOUT = "locating_to";
         private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
         private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
+        private static final String KEY_MOTION_INACTIVE_TIMEOUT_FLEX = "motion_inactive_to_flex";
         private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
         private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
         private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
@@ -929,13 +935,20 @@
                 "pre_idle_factor_long";
         private static final String KEY_PRE_IDLE_FACTOR_SHORT =
                 "pre_idle_factor_short";
+        private static final String KEY_USE_WINDOW_ALARMS = "use_window_alarms";
 
+        private static final long DEFAULT_FLEX_TIME_SHORT =
+                !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
         private static final long DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
-                !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L;
+                !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L;
         private static final long DEFAULT_LIGHT_PRE_IDLE_TIMEOUT =
                 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L;
         private static final long DEFAULT_LIGHT_IDLE_TIMEOUT =
                 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L;
+        private static final long DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX =
+                !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
+        private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX =
+                !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
         private static final float DEFAULT_LIGHT_IDLE_FACTOR = 2f;
         private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT =
                 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
@@ -958,6 +971,8 @@
         private static final float DEFAULT_LOCATION_ACCURACY = 20f;
         private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT =
                 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
+        private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX =
+                !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
         private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT =
                 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY =
@@ -983,6 +998,14 @@
         private static final boolean DEFAULT_WAIT_FOR_UNLOCK = true;
         private static final float DEFAULT_PRE_IDLE_FACTOR_LONG = 1.67f;
         private static final float DEFAULT_PRE_IDLE_FACTOR_SHORT = .33f;
+        private static final boolean DEFAULT_USE_WINDOW_ALARMS = true;
+
+        /**
+         * A somewhat short alarm window size that we will tolerate for various alarm timings.
+         *
+         * @see #KEY_FLEX_TIME_SHORT
+         */
+        public long FLEX_TIME_SHORT = DEFAULT_FLEX_TIME_SHORT;
 
         /**
          * This is the time, after becoming inactive, that we go in to the first
@@ -1002,13 +1025,28 @@
         public long LIGHT_PRE_IDLE_TIMEOUT = DEFAULT_LIGHT_PRE_IDLE_TIMEOUT;
 
         /**
-         * This is the initial time that we will run in idle maintenance mode.
+         * This is the initial time that we will run in light idle maintenance mode.
          *
          * @see #KEY_LIGHT_IDLE_TIMEOUT
          */
         public long LIGHT_IDLE_TIMEOUT = DEFAULT_LIGHT_IDLE_TIMEOUT;
 
         /**
+         * This is the initial alarm window size that we will tolerate for light idle maintenance
+         * timing.
+         *
+         * @see #KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX
+         */
+        public long LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX;
+
+        /**
+         * This is the maximum value that {@link #LIGHT_IDLE_TIMEOUT_INITIAL_FLEX} should take.
+         *
+         * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX
+         */
+        public long LIGHT_MAX_IDLE_TIMEOUT_FLEX = DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX;
+
+        /**
          * Scaling factor to apply to the light idle mode time each time we complete a cycle.
          *
          * @see #KEY_LIGHT_IDLE_FACTOR
@@ -1016,7 +1054,7 @@
         public float LIGHT_IDLE_FACTOR = DEFAULT_LIGHT_IDLE_FACTOR;
 
         /**
-         * This is the maximum time we will run in idle maintenance mode.
+         * This is the maximum time we will stay in light idle mode.
          *
          * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
          */
@@ -1099,13 +1137,22 @@
         /**
          * This is the time, after seeing motion, that we wait after becoming inactive from
          * that until we start looking for motion again.
+         *
          * @see #KEY_MOTION_INACTIVE_TIMEOUT
          */
         public long MOTION_INACTIVE_TIMEOUT = DEFAULT_MOTION_INACTIVE_TIMEOUT;
 
         /**
+         * This is the alarm window size we will tolerate for motion detection timings.
+         *
+         * @see #KEY_MOTION_INACTIVE_TIMEOUT_FLEX
+         */
+        public long MOTION_INACTIVE_TIMEOUT_FLEX = DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX;
+
+        /**
          * This is the time, after the inactive timeout elapses, that we will wait looking
          * for motion until we truly consider the device to be idle.
+         *
          * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
          */
         public long IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
@@ -1204,6 +1251,12 @@
 
         public boolean WAIT_FOR_UNLOCK = DEFAULT_WAIT_FOR_UNLOCK;
 
+        /**
+         * Whether to use window alarms. True to use window alarms (call AlarmManager.setWindow()).
+         * False to use the legacy inexact alarms (call AlarmManager.set()).
+         */
+        public boolean USE_WINDOW_ALARMS = DEFAULT_USE_WINDOW_ALARMS;
+
         private final boolean mSmallBatteryDevice;
 
         public Constants() {
@@ -1227,6 +1280,10 @@
                         continue;
                     }
                     switch (name) {
+                        case KEY_FLEX_TIME_SHORT:
+                            FLEX_TIME_SHORT = properties.getLong(
+                                    KEY_FLEX_TIME_SHORT, DEFAULT_FLEX_TIME_SHORT);
+                            break;
                         case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
                             LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
                                     KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
@@ -1240,9 +1297,19 @@
                             LIGHT_IDLE_TIMEOUT = properties.getLong(
                                     KEY_LIGHT_IDLE_TIMEOUT, DEFAULT_LIGHT_IDLE_TIMEOUT);
                             break;
+                        case KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX:
+                            LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = properties.getLong(
+                                    KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
+                                    DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX);
+                            break;
+                        case KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX:
+                            LIGHT_MAX_IDLE_TIMEOUT_FLEX = properties.getLong(
+                                    KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX,
+                                    DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX);
+                            break;
                         case KEY_LIGHT_IDLE_FACTOR:
-                            LIGHT_IDLE_FACTOR = properties.getFloat(
-                                    KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR);
+                            LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
+                                    KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR));
                             break;
                         case KEY_LIGHT_MAX_IDLE_TIMEOUT:
                             LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
@@ -1291,6 +1358,11 @@
                             MOTION_INACTIVE_TIMEOUT = properties.getLong(
                                     KEY_MOTION_INACTIVE_TIMEOUT, DEFAULT_MOTION_INACTIVE_TIMEOUT);
                             break;
+                        case KEY_MOTION_INACTIVE_TIMEOUT_FLEX:
+                            MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong(
+                                    KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
+                                    DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX);
+                            break;
                         case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
                             final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
                                     ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
@@ -1362,6 +1434,10 @@
                             PRE_IDLE_FACTOR_SHORT = properties.getFloat(
                                     KEY_PRE_IDLE_FACTOR_SHORT, DEFAULT_PRE_IDLE_FACTOR_SHORT);
                             break;
+                        case KEY_USE_WINDOW_ALARMS:
+                            USE_WINDOW_ALARMS = properties.getBoolean(
+                                    KEY_USE_WINDOW_ALARMS, DEFAULT_USE_WINDOW_ALARMS);
+                            break;
                         default:
                             Slog.e(TAG, "Unknown configuration key: " + name);
                             break;
@@ -1373,6 +1449,10 @@
         void dump(PrintWriter pw) {
             pw.println("  Settings:");
 
+            pw.print("    "); pw.print(KEY_FLEX_TIME_SHORT); pw.print("=");
+            TimeUtils.formatDuration(FLEX_TIME_SHORT, pw);
+            pw.println();
+
             pw.print("    ");
             pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
             pw.print("=");
@@ -1387,6 +1467,14 @@
             TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
             pw.println();
 
+            pw.print("    "); pw.print(KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX); pw.print("=");
+            TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT_INITIAL_FLEX, pw);
+            pw.println();
+
+            pw.print("    "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX); pw.print("=");
+            TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT_FLEX, pw);
+            pw.println();
+
             pw.print("    "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
             pw.print(LIGHT_IDLE_FACTOR);
             pw.println();
@@ -1431,6 +1519,10 @@
             TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
             pw.println();
 
+            pw.print("    "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT_FLEX); pw.print("=");
+            TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT_FLEX, pw);
+            pw.println();
+
             pw.print("    "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
             TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
             pw.println();
@@ -1489,6 +1581,9 @@
 
             pw.print("    "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("=");
             pw.println(PRE_IDLE_FACTOR_SHORT);
+
+            pw.print("    "); pw.print(KEY_USE_WINDOW_ALARMS); pw.print("=");
+            pw.println(USE_WINDOW_ALARMS);
         }
     }
 
@@ -3199,7 +3294,8 @@
             mLightState = LIGHT_STATE_INACTIVE;
             if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
             resetLightIdleManagementLocked();
-            scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+            scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
+                    mConstants.FLEX_TIME_SHORT);
             EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
         }
     }
@@ -3219,6 +3315,7 @@
 
     private void resetLightIdleManagementLocked() {
         mNextLightIdleDelay = 0;
+        mNextLightIdleDelayFlex = 0;
         mCurLightIdleBudget = 0;
         cancelLightAlarmLocked();
     }
@@ -3265,13 +3362,15 @@
                 mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
                 // Reset the upcoming idle delays.
                 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
+                mNextLightIdleDelayFlex = mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX;
                 mMaintenanceStartTime = 0;
                 if (!isOpsInactiveLocked()) {
                     // We have some active ops going on...  give them a chance to finish
                     // before going in to our first idle.
                     mLightState = LIGHT_STATE_PRE_IDLE;
                     EventLogTags.writeDeviceIdleLight(mLightState, reason);
-                    scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
+                    scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT,
+                            mConstants.FLEX_TIME_SHORT);
                     break;
                 }
                 // Nothing active, fall through to immediately idle.
@@ -3290,12 +3389,11 @@
                     }
                 }
                 mMaintenanceStartTime = 0;
-                scheduleLightAlarmLocked(mNextLightIdleDelay);
+                scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex);
                 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
-                        (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
-                if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
-                    mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
-                }
+                        (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
+                mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX,
+                        (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR));
                 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
                 mLightState = LIGHT_STATE_IDLE;
                 EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -3315,7 +3413,7 @@
                     } else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
                         mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
                     }
-                    scheduleLightAlarmLocked(mCurLightIdleBudget);
+                    scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT);
                     if (DEBUG) Slog.d(TAG,
                             "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
                     mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
@@ -3326,7 +3424,7 @@
                     // We'd like to do maintenance, but currently don't have network
                     // connectivity...  let's try to wait until the network comes back.
                     // We'll only wait for another full idle period, however, and then give up.
-                    scheduleLightAlarmLocked(mNextLightIdleDelay);
+                    scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex / 2);
                     if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
                     mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
                     EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -3844,40 +3942,75 @@
             mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                     mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
         } else {
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+            if (mConstants.USE_WINDOW_ALARMS) {
+                mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        mConstants.FLEX_TIME_SHORT,
+                        mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+            } else {
+                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+            }
         }
     }
 
-    void scheduleLightAlarmLocked(long delay) {
-        if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
+    void scheduleLightAlarmLocked(long delay, long flex) {
+        if (DEBUG) {
+            Slog.d(TAG, "scheduleLightAlarmLocked(" + delay
+                    + (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") + ")");
+        }
         mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
+        if (mConstants.USE_WINDOW_ALARMS) {
+            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, flex,
+                    "DeviceIdleController.light", mLightAlarmListener, mHandler);
+        } else {
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime,
+                    "DeviceIdleController.light", mLightAlarmListener, mHandler);
+        }
     }
 
     private void scheduleMotionRegistrationAlarmLocked() {
         if (DEBUG) Slog.d(TAG, "scheduleMotionRegistrationAlarmLocked");
         long nextMotionRegistrationAlarmTime =
                 mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT / 2;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime,
-                "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
-                mHandler);
+        if (mConstants.USE_WINDOW_ALARMS) {
+            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    nextMotionRegistrationAlarmTime, mConstants.MOTION_INACTIVE_TIMEOUT_FLEX,
+                    "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
+                    mHandler);
+        } else {
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime,
+                    "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
+                    mHandler);
+        }
     }
 
     private void scheduleMotionTimeoutAlarmLocked() {
         if (DEBUG) Slog.d(TAG, "scheduleMotionAlarmLocked");
         long nextMotionTimeoutAlarmTime =
                 mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionTimeoutAlarmTime,
-                "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+        if (mConstants.USE_WINDOW_ALARMS) {
+            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    nextMotionTimeoutAlarmTime,
+                    mConstants.MOTION_INACTIVE_TIMEOUT_FLEX,
+                    "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+        } else {
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionTimeoutAlarmTime,
+                    "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+        }
     }
 
     void scheduleSensingTimeoutAlarmLocked(long delay) {
         if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
         mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
-            "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+        if (mConstants.USE_WINDOW_ALARMS) {
+            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    mNextSensingTimeoutAlarmTime,
+                    mConstants.FLEX_TIME_SHORT,
+                    "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+        } else {
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
+                    "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+        }
     }
 
     private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
@@ -4852,7 +4985,13 @@
             if (mNextLightIdleDelay != 0) {
                 pw.print("  mNextIdleDelay=");
                 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
-                pw.println();
+                if (mConstants.USE_WINDOW_ALARMS) {
+                    pw.print(" (flex=");
+                    TimeUtils.formatDuration(mNextLightIdleDelayFlex, pw);
+                    pw.println(")");
+                } else {
+                    pw.println();
+                }
             }
             if (mNextLightAlarmTime != 0) {
                 pw.print("  mNextLightAlarmTime=");
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 96d59b8..9bd6c750f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -4804,6 +4804,16 @@
     public static final int HISTORY_FLAG_DISCRETE = 1 << 1;
 
     /**
+     * Flag for querying app op history: assemble attribution chains, and attach the last visible
+     * node in the chain to the start as a proxy info. This only applies to discrete accesses.
+     *
+     * TODO 191512294: Add to @SystemApi
+     *
+     * @hide
+     */
+    public static final int HISTORY_FLAG_GET_ATTRIBUTION_CHAINS = 1 << 2;
+
+    /**
      * Flag for querying app op history: get all types of historical access information.
      *
      * @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer)
@@ -4819,7 +4829,8 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = true, prefix = { "HISTORY_FLAG_" }, value = {
             HISTORY_FLAG_AGGREGATE,
-            HISTORY_FLAG_DISCRETE
+            HISTORY_FLAG_DISCRETE,
+            HISTORY_FLAG_GET_ATTRIBUTION_CHAINS
     })
     public @interface OpHistoryFlags {}
 
@@ -5037,7 +5048,8 @@
              * @return This builder.
              */
             public @NonNull Builder setHistoryFlags(@OpHistoryFlags int flags) {
-                Preconditions.checkFlagsArgument(flags, HISTORY_FLAGS_ALL);
+                Preconditions.checkFlagsArgument(flags,
+                        HISTORY_FLAGS_ALL | HISTORY_FLAG_GET_ATTRIBUTION_CHAINS);
                 mHistoryFlags = flags;
                 return this;
             }
@@ -5290,8 +5302,17 @@
                 @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag,
                 long discreteAccessTime, long discreteAccessDuration) {
             getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag,
-                    uidState, opFlag, discreteAccessTime, discreteAccessDuration);
-        };
+                    uidState, opFlag, discreteAccessTime, discreteAccessDuration, null);
+        }
+
+        /** @hide */
+        public void addDiscreteAccess(int opCode, int uid, @NonNull String packageName,
+                @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag,
+                long discreteAccessTime, long discreteAccessDuration,
+                @Nullable OpEventProxyInfo proxy) {
+            getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag,
+                    uidState, opFlag, discreteAccessTime, discreteAccessDuration, proxy);
+        }
 
 
         /** @hide */
@@ -5623,9 +5644,10 @@
 
         private void addDiscreteAccess(int opCode, @NonNull String packageName,
                 @Nullable String attributionTag, @UidState int uidState,
-                @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration) {
+                @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration,
+                @Nullable OpEventProxyInfo proxy) {
             getOrCreateHistoricalPackageOps(packageName).addDiscreteAccess(opCode, attributionTag,
-                    uidState, flag, discreteAccessTime, discreteAccessDuration);
+                    uidState, flag, discreteAccessTime, discreteAccessDuration, proxy);
         };
 
         /**
@@ -5889,9 +5911,9 @@
 
         private void addDiscreteAccess(int opCode, @Nullable String attributionTag,
                 @UidState int uidState, @OpFlags int flag, long discreteAccessTime,
-                long discreteAccessDuration) {
+                long discreteAccessDuration, @Nullable OpEventProxyInfo proxy) {
             getOrCreateAttributedHistoricalOps(attributionTag).addDiscreteAccess(opCode, uidState,
-                    flag, discreteAccessTime, discreteAccessDuration);
+                    flag, discreteAccessTime, discreteAccessDuration, proxy);
         }
 
         /**
@@ -6212,9 +6234,10 @@
         }
 
         private void addDiscreteAccess(int opCode, @UidState int uidState, @OpFlags int flag,
-                long discreteAccessTime, long discreteAccessDuration) {
+                long discreteAccessTime, long discreteAccessDuration,
+                @Nullable OpEventProxyInfo proxy) {
             getOrCreateHistoricalOp(opCode).addDiscreteAccess(uidState,flag, discreteAccessTime,
-                    discreteAccessDuration);
+                    discreteAccessDuration, proxy);
         }
 
         /**
@@ -6583,11 +6606,12 @@
         }
 
         private void addDiscreteAccess(@UidState int uidState, @OpFlags int flag,
-                long discreteAccessTime, long discreteAccessDuration) {
+                long discreteAccessTime, long discreteAccessDuration,
+                @Nullable OpEventProxyInfo proxy) {
             List<AttributedOpEntry> discreteAccesses = getOrCreateDiscreteAccesses();
             LongSparseArray<NoteOpEvent> accessEvents = new LongSparseArray<>();
             long key = makeKey(uidState, flag);
-            NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, null);
+            NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, proxy);
             accessEvents.append(key, note);
             AttributedOpEntry access = new AttributedOpEntry(mOp, false, accessEvents, null);
             int insertionPoint = discreteAccesses.size() - 1;
@@ -10022,6 +10046,8 @@
                     NoteOpEvent existingAccess = accessEvents.get(key);
                     if (existingAccess == null || existingAccess.getDuration() == -1) {
                         accessEvents.append(key, access);
+                    } else if (existingAccess.mProxy == null && access.mProxy != null ) {
+                        existingAccess.mProxy = access.mProxy;
                     }
                 }
                 if (reject != null) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 9ed76c1..a2c9795 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -546,6 +546,10 @@
         if (aInfo.sharedLibraryFiles != null) {
             int index = 0;
             for (String lib : aInfo.sharedLibraryFiles) {
+                // sharedLibraryFiles might contain native shared libraries that are not APK paths.
+                if (!lib.endsWith(".apk")) {
+                    continue;
+                }
                 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
                     outZipPaths.add(index, lib);
                     index++;
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index 2777a7a..7ef0a19 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -420,7 +420,7 @@
         for (Map.Entry<Integer, Integer> colorEntry : mAllColors.entrySet()) {
             if (colorEntry.getKey() != null) {
                 dest.writeInt(colorEntry.getKey());
-                Integer population = mAllColors.get(colorEntry.getValue());
+                Integer population = colorEntry.getValue();
                 int populationInt = (population != null) ? population : 0;
                 dest.writeInt(populationInt);
             }
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index eb4c624..585eb61 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -68,5 +68,5 @@
     void reportUserInteraction(String packageName, int userId);
     int getUsageSource();
     void forceUsageSourceSettingRead();
-    long getLastTimeAnyComponentUsed(String packageName);
+    long getLastTimeAnyComponentUsed(String packageName, String callingPackage);
 }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index e8175c7..ac7a318 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -1287,7 +1287,7 @@
             android.Manifest.permission.PACKAGE_USAGE_STATS})
     public long getLastTimeAnyComponentUsed(@NonNull String packageName) {
         try {
-            return mService.getLastTimeAnyComponentUsed(packageName);
+            return mService.getLastTimeAnyComponentUsed(packageName, mContext.getOpPackageName());
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ded5e6e..5b72b76 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3054,6 +3054,9 @@
                 return true;
             }
             return false;
+        } else if (profile == BluetoothProfile.LE_AUDIO) {
+            BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this);
+            return true;
         } else {
             return false;
         }
@@ -3142,6 +3145,10 @@
             case BluetoothProfile.HEARING_AID:
                 BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy;
                 hearingAid.close();
+                break;
+            case BluetoothProfile.LE_AUDIO:
+                BluetoothLeAudio leAudio = (BluetoothLeAudio) proxy;
+                leAudio.close();
         }
     }
 
diff --git a/core/java/android/companion/OWNERS b/core/java/android/companion/OWNERS
index da723b3..54b35fc 100644
--- a/core/java/android/companion/OWNERS
+++ b/core/java/android/companion/OWNERS
@@ -1 +1,4 @@
-eugenesusla@google.com
\ No newline at end of file
+ewol@google.com
+evanxinchen@google.com
+guojing@google.com
+svetoslavganov@google.com
\ No newline at end of file
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 37469e9..08f5a8a 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -848,8 +848,10 @@
     /**
      * Get the highest supported direct report mode rate level of the sensor.
      *
-     * @return Highest direct report rate level of this sensor. If the sensor does not support
-     * direct report mode, this returns {@link SensorDirectChannel#RATE_STOP}.
+     * @return Highest direct report rate level of this sensor. Note that if the app does not have
+     * the {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission, the highest
+     * direct report rate level is {@link SensorDirectChannel#RATE_NORMAL}. If the sensor
+     * does not support direct report mode, this returns {@link SensorDirectChannel#RATE_STOP}.
      * @see SensorDirectChannel#RATE_STOP
      * @see SensorDirectChannel#RATE_NORMAL
      * @see SensorDirectChannel#RATE_FAST
@@ -1002,9 +1004,11 @@
     }
 
     /**
-     * @return the minimum delay allowed between two events in microsecond
+     * @return the minimum delay allowed between two events in microseconds
      * or zero if this sensor only returns a value when the data it's measuring
-     * changes.
+     * changes. Note that if the app does not have the
+     * {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission, the
+     * minimum delay is capped at 5000 microseconds (200 Hz).
      */
     public int getMinDelay() {
         return mMinDelay;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 713b66a..572a8a8 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -46,6 +46,13 @@
  * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION}
  * is an example of a trigger sensor.
  * </p>
+ * <p>
+ * In order to access sensor data at high sampling rates (i.e. greater than 200 Hz
+ * for {@link SensorEventListener} and greater than {@link SensorDirectChannel#RATE_NORMAL}
+ * for {@link SensorDirectChannel}), apps must declare
+ * the {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission
+ * in their AndroidManifest.xml file.
+ * </p>
  * <pre class="prettyprint">
  * public class SensorActivity extends Activity implements SensorEventListener {
  *     private final SensorManager mSensorManager;
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 2d46a407..e665d0f 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -208,7 +208,8 @@
             FINGERPRINT_ACQUIRED_TOO_FAST,
             FINGERPRINT_ACQUIRED_VENDOR,
             FINGERPRINT_ACQUIRED_START,
-            FINGERPRINT_ACQUIRED_UNKNOWN})
+            FINGERPRINT_ACQUIRED_UNKNOWN,
+            FINGERPRINT_ACQUIRED_IMMOBILE})
     @Retention(RetentionPolicy.SOURCE)
     @interface FingerprintAcquired {}
 
@@ -278,6 +279,14 @@
     int FINGERPRINT_ACQUIRED_UNKNOWN = 8;
 
     /**
+     * This message may be sent during enrollment if the same area of the finger has already
+     * been captured during this enrollment session. In general, enrolling multiple areas of the
+     * same finger can help against false rejections.
+     * @hide
+     */
+    int FINGERPRINT_ACQUIRED_IMMOBILE = 9;
+
+    /**
      * @hide
      */
     int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index e24332a..5b259f7 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -212,9 +212,9 @@
      */
     private static final class CameraExtensionManagerGlobal {
         private static final String TAG = "CameraExtensionManagerGlobal";
-        private static final String PROXY_PACKAGE_NAME = "com.android.camera";
+        private static final String PROXY_PACKAGE_NAME = "com.android.cameraextensions";
         private static final String PROXY_SERVICE_NAME =
-                "com.android.camera.CameraExtensionsProxyService";
+                "com.android.cameraextensions.CameraExtensionsProxyService";
 
         // Singleton instance
         private static final CameraExtensionManagerGlobal GLOBAL_CAMERA_MANAGER =
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 688f9f1..0819835 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1417,6 +1417,9 @@
             case FINGERPRINT_ACQUIRED_TOO_FAST:
                 return context.getString(
                     com.android.internal.R.string.fingerprint_acquired_too_fast);
+            case FINGERPRINT_ACQUIRED_IMMOBILE:
+                return context.getString(
+                    com.android.internal.R.string.fingerprint_acquired_immobile);
             case FINGERPRINT_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         com.android.internal.R.array.fingerprint_acquired_vendor);
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 662ebb3..5c28553 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -389,6 +389,10 @@
 
     /**
      * Starts a legacy VPN.
+     *
+     * Legacy VPN is deprecated starting from Android S. So this API shouldn't be called if the
+     * initial SDK version of device is Android S+. Otherwise, UnsupportedOperationException will be
+     * thrown.
      * @hide
      */
     public void startLegacyVpn(VpnProfile profile) {
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index 86cd23d..752ef3e 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -352,6 +352,7 @@
     public int hashCode() {
         return Objects.hash(
                 mGatewayConnectionName,
+                mTunnelConnectionParams,
                 mExposedCapabilities,
                 Arrays.hashCode(mRetryIntervalsMs),
                 mMaxMtu);
@@ -365,6 +366,7 @@
 
         final VcnGatewayConnectionConfig rhs = (VcnGatewayConnectionConfig) other;
         return mGatewayConnectionName.equals(rhs.mGatewayConnectionName)
+                && mTunnelConnectionParams.equals(rhs.mTunnelConnectionParams)
                 && mExposedCapabilities.equals(rhs.mExposedCapabilities)
                 && Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs)
                 && mMaxMtu == rhs.mMaxMtu;
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index fd8948c..0c3debb1 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -26,6 +26,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.Objects;
@@ -254,11 +255,14 @@
      * <p>This uses the first vibrator on the list as the default one for all hardware spec, but
      * uses an intersection of all vibrators to decide the capabilities and effect/primitive
      * support.
+     *
+     * @hide
      */
-    private static class AllVibratorsInfo extends VibratorInfo {
+    @VisibleForTesting
+    public static class AllVibratorsInfo extends VibratorInfo {
         private final VibratorInfo[] mVibratorInfos;
 
-        AllVibratorsInfo(VibratorInfo[] vibrators) {
+        public AllVibratorsInfo(VibratorInfo[] vibrators) {
             super(/* id= */ -1, capabilitiesIntersection(vibrators),
                     vibrators.length > 0 ? vibrators[0] : VibratorInfo.EMPTY_VIBRATOR_INFO);
             mVibratorInfos = vibrators;
@@ -266,6 +270,9 @@
 
         @Override
         public int isEffectSupported(int effectId) {
+            if (mVibratorInfos.length == 0) {
+                return Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
+            }
             int supported = Vibrator.VIBRATION_EFFECT_SUPPORT_YES;
             for (VibratorInfo info : mVibratorInfos) {
                 int effectSupported = info.isEffectSupported(effectId);
@@ -280,6 +287,9 @@
 
         @Override
         public boolean isPrimitiveSupported(int primitiveId) {
+            if (mVibratorInfos.length == 0) {
+                return false;
+            }
             for (VibratorInfo info : mVibratorInfos) {
                 if (!info.isPrimitiveSupported(primitiveId)) {
                     return false;
@@ -288,6 +298,19 @@
             return true;
         }
 
+        @Override
+        public int getPrimitiveDuration(int primitiveId) {
+            int maxDuration = 0;
+            for (VibratorInfo info : mVibratorInfos) {
+                int duration = info.getPrimitiveDuration(primitiveId);
+                if (duration == 0) {
+                    return 0;
+                }
+                maxDuration = Math.max(maxDuration, duration);
+            }
+            return maxDuration;
+        }
+
         private static int capabilitiesIntersection(VibratorInfo[] infos) {
             if (infos.length == 0) {
                 return 0;
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index c5d0cd4..4ef0e6e 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -908,9 +908,32 @@
      */
     public static boolean shouldShowPackageForIndicatorCached(@NonNull Context context,
             @NonNull String packageName) {
-        if (SYSTEM_PKG.equals(packageName)) {
-            return false;
+        return !getIndicatorExemptedPackages(context).contains(packageName);
+    }
+
+    /**
+     * Get the list of packages that are not shown by the indicators. Only a select few roles, and
+     * the system app itself, are hidden. These values are updated at most every 15 seconds.
+     * @hide
+     */
+    public static Set<String> getIndicatorExemptedPackages(@NonNull Context context) {
+        updateIndicatorExemptedPackages(context);
+        ArraySet<String> pkgNames = new ArraySet<>();
+        pkgNames.add(SYSTEM_PKG);
+        for (int i = 0; i < INDICATOR_EXEMPTED_PACKAGES.length; i++) {
+            String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i];
+            if (exemptedPackage != null) {
+                pkgNames.add(exemptedPackage);
+            }
         }
+        return pkgNames;
+    }
+
+    /**
+     * Update the cached indicator exempted packages
+     * @hide
+     */
+    public static void updateIndicatorExemptedPackages(@NonNull Context context) {
         long now = SystemClock.elapsedRealtime();
         if (sLastIndicatorUpdateTime == -1
                 || (now - sLastIndicatorUpdateTime) > EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS) {
@@ -919,14 +942,6 @@
                 INDICATOR_EXEMPTED_PACKAGES[i] = context.getString(EXEMPTED_ROLES[i]);
             }
         }
-        for (int i = 0; i < EXEMPTED_ROLES.length; i++) {
-            String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i];
-            if (exemptedPackage != null && exemptedPackage.equals(packageName)) {
-                return false;
-            }
-        }
-
-        return true;
     }
     /**
      * Gets the list of packages that have permissions that specified
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index d4e548e..791764b 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -410,7 +410,9 @@
 
             int usageAttr = usage.getPackageIdHash();
             // If this usage has a proxy, but is not a proxy, it is the end of a chain.
-            if (!proxies.containsKey(usageAttr) && usage.proxy != null) {
+            // TODO remove once camera converted
+            if (!proxies.containsKey(usageAttr) && usage.proxy != null
+                    && !usage.op.equals(OPSTR_RECORD_AUDIO)) {
                 proxyLabels.put(usage, new ArrayList<>());
                 proxyPackages.add(usage.getPackageIdHash());
             }
diff --git a/core/java/android/service/contentcapture/ActivityEvent.java b/core/java/android/service/contentcapture/ActivityEvent.java
index 1188a3f..74a7355 100644
--- a/core/java/android/service/contentcapture/ActivityEvent.java
+++ b/core/java/android/service/contentcapture/ActivityEvent.java
@@ -55,12 +55,25 @@
      */
     public static final int TYPE_ACTIVITY_DESTROYED = Event.ACTIVITY_DESTROYED;
 
+    /**
+     * TODO: change to public field.
+     * The activity was started.
+     *
+     * <p>There are some reason, ACTIVITY_START cannot be added into UsageStats. We don't depend on
+     * UsageEvents for Activity start.
+     * </p>
+     *
+     * @hide
+     */
+    public static final int TYPE_ACTIVITY_STARTED = 10000;
+
     /** @hide */
     @IntDef(prefix = { "TYPE_" }, value = {
             TYPE_ACTIVITY_RESUMED,
             TYPE_ACTIVITY_PAUSED,
             TYPE_ACTIVITY_STOPPED,
-            TYPE_ACTIVITY_DESTROYED
+            TYPE_ACTIVITY_DESTROYED,
+            TYPE_ACTIVITY_STARTED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActivityEventType{}
@@ -86,7 +99,8 @@
      * Gets the event type.
      *
      * @return either {@link #TYPE_ACTIVITY_RESUMED}, {@value #TYPE_ACTIVITY_PAUSED},
-     * {@value #TYPE_ACTIVITY_STOPPED}, or {@value #TYPE_ACTIVITY_DESTROYED}.
+     * {@value #TYPE_ACTIVITY_STOPPED}, {@value #TYPE_ACTIVITY_DESTROYED} or 10000 if the Activity
+     * was started.
      */
     @ActivityEventType
     public int getEventType() {
@@ -104,6 +118,8 @@
                 return "ACTIVITY_STOPPED";
             case TYPE_ACTIVITY_DESTROYED:
                 return "ACTIVITY_DESTROYED";
+            case TYPE_ACTIVITY_STARTED:
+                return "ACTIVITY_STARTED";
             default:
                 return "UKNOWN_TYPE: " + type;
         }
diff --git a/core/java/android/service/voice/HotwordDetectedResult.java b/core/java/android/service/voice/HotwordDetectedResult.java
index 846f2f9..315392b 100644
--- a/core/java/android/service/voice/HotwordDetectedResult.java
+++ b/core/java/android/service/voice/HotwordDetectedResult.java
@@ -20,11 +20,18 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.res.Resources;
+import android.media.AudioRecord;
 import android.media.MediaSyncEvent;
+import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.internal.R;
 import com.android.internal.util.DataClass;
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
 
 /**
  * Represents a result supporting the hotword detection.
@@ -187,16 +194,20 @@
         return new PersistableBundle();
     }
 
+    private static int sMaxBundleSize = -1;
+
     /**
      * Returns the maximum byte size of the information contained in the bundle.
      *
-     * <p>The total size will be calculated as a sum of byte sizes over all bundle keys.
-     *
-     * <p>For example, for a bundle containing a single key: {@code "example_key" -> 42.0f}, the
-     * bundle size will be {@code 11 + Float.BYTES = 15} bytes.
+     * <p>The total size will be calculated by how much bundle data should be written into the
+     * Parcel.
      */
     public static int getMaxBundleSize() {
-        return 50;
+        if (sMaxBundleSize < 0) {
+            sMaxBundleSize = Resources.getSystem().getInteger(
+                    R.integer.config_hotwordDetectedResultMaxBundleSize);
+        }
+        return sMaxBundleSize;
     }
 
     /**
@@ -212,6 +223,34 @@
         return mMediaSyncEvent;
     }
 
+    /**
+     * Returns how many bytes should be written into the Parcel
+     *
+     * @hide
+     */
+    public static int getParcelableSize(@NonNull Parcelable parcelable) {
+        final Parcel p = Parcel.obtain();
+        parcelable.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        final int size = p.dataSize();
+        p.recycle();
+        return size;
+    }
+
+    private void onConstructed() {
+        Preconditions.checkArgumentInRange(mScore, 0, getMaxScore(), "score");
+        Preconditions.checkArgumentInRange(mPersonalizedScore, 0, getMaxScore(),
+                "personalizedScore");
+        Preconditions.checkArgumentInRange(mHotwordPhraseId, 0, getMaxHotwordPhraseId(),
+                "hotwordPhraseId");
+        Preconditions.checkArgumentInRange((long) mHotwordDurationMillis, 0,
+                AudioRecord.getMaxSharedAudioHistoryMillis(), "hotwordDurationMillis");
+        if (!mExtras.isEmpty()) {
+            Preconditions.checkArgumentInRange(getParcelableSize(mExtras), 0, getMaxBundleSize(),
+                    "extras");
+        }
+    }
+
 
 
     // Code below generated by codegen v1.0.23.
@@ -290,7 +329,7 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mExtras);
 
-        // onConstructed(); // You can define this method to get a callback
+        onConstructed();
     }
 
     /**
@@ -422,7 +461,7 @@
         //noinspection PointlessBooleanExpression
         return true
                 && mConfidenceLevel == that.mConfidenceLevel
-                && java.util.Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent)
+                && Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent)
                 && mHotwordOffsetMillis == that.mHotwordOffsetMillis
                 && mHotwordDurationMillis == that.mHotwordDurationMillis
                 && mAudioChannel == that.mAudioChannel
@@ -430,7 +469,7 @@
                 && mScore == that.mScore
                 && mPersonalizedScore == that.mPersonalizedScore
                 && mHotwordPhraseId == that.mHotwordPhraseId
-                && java.util.Objects.equals(mExtras, that.mExtras);
+                && Objects.equals(mExtras, that.mExtras);
     }
 
     @Override
@@ -441,7 +480,7 @@
 
         int _hash = 1;
         _hash = 31 * _hash + mConfidenceLevel;
-        _hash = 31 * _hash + java.util.Objects.hashCode(mMediaSyncEvent);
+        _hash = 31 * _hash + Objects.hashCode(mMediaSyncEvent);
         _hash = 31 * _hash + mHotwordOffsetMillis;
         _hash = 31 * _hash + mHotwordDurationMillis;
         _hash = 31 * _hash + mAudioChannel;
@@ -449,13 +488,13 @@
         _hash = 31 * _hash + mScore;
         _hash = 31 * _hash + mPersonalizedScore;
         _hash = 31 * _hash + mHotwordPhraseId;
-        _hash = 31 * _hash + java.util.Objects.hashCode(mExtras);
+        _hash = 31 * _hash + Objects.hashCode(mExtras);
         return _hash;
     }
 
     @Override
     @DataClass.Generated.Member
-    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
@@ -481,7 +520,7 @@
     /** @hide */
     @SuppressWarnings({"unchecked", "RedundantCast"})
     @DataClass.Generated.Member
-    /* package-private */ HotwordDetectedResult(@NonNull android.os.Parcel in) {
+    /* package-private */ HotwordDetectedResult(@NonNull Parcel in) {
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
@@ -512,7 +551,7 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mExtras);
 
-        // onConstructed(); // You can define this method to get a callback
+        onConstructed();
     }
 
     @DataClass.Generated.Member
@@ -524,7 +563,7 @@
         }
 
         @Override
-        public HotwordDetectedResult createFromParcel(@NonNull android.os.Parcel in) {
+        public HotwordDetectedResult createFromParcel(@NonNull Parcel in) {
             return new HotwordDetectedResult(in);
         }
     };
@@ -745,10 +784,10 @@
     }
 
     @DataClass.Generated(
-            time = 1621943150502L,
+            time = 1624361647985L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java",
-            inputSignatures = "public static final  int CONFIDENCE_LEVEL_NONE\npublic static final  int CONFIDENCE_LEVEL_LOW\npublic static final  int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final  int CONFIDENCE_LEVEL_HIGH\npublic static final  int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final  int HOTWORD_OFFSET_UNSET\npublic static final  int AUDIO_CHANNEL_UNSET\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate  int mHotwordOffsetMillis\nprivate  int mHotwordDurationMillis\nprivate  int mAudioChannel\nprivate  boolean mHotwordDetectionPersonalized\nprivate final  int mScore\nprivate final  int mPersonalizedScore\nprivate final  int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultScore()\nprivate static  int defaultPersonalizedScore()\npublic static  int getMaxScore()\nprivate static  int defaultHotwordPhraseId()\npublic static  int getMaxHotwordPhraseId()\nprivate static  android.os.PersistableBundle defaultExtras()\npublic static  int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
+            inputSignatures = "public static final  int CONFIDENCE_LEVEL_NONE\npublic static final  int CONFIDENCE_LEVEL_LOW\npublic static final  int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final  int CONFIDENCE_LEVEL_HIGH\npublic static final  int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final  int HOTWORD_OFFSET_UNSET\npublic static final  int AUDIO_CHANNEL_UNSET\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate  int mHotwordOffsetMillis\nprivate  int mHotwordDurationMillis\nprivate  int mAudioChannel\nprivate  boolean mHotwordDetectionPersonalized\nprivate final  int mScore\nprivate final  int mPersonalizedScore\nprivate final  int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static  int sMaxBundleSize\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultScore()\nprivate static  int defaultPersonalizedScore()\npublic static  int getMaxScore()\nprivate static  int defaultHotwordPhraseId()\npublic static  int getMaxHotwordPhraseId()\nprivate static  android.os.PersistableBundle defaultExtras()\npublic static  int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static  int getParcelableSize(android.os.Parcelable)\nprivate  void onConstructed()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index 93a7ec7..567ee2f 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -76,6 +76,7 @@
     private static final boolean DBG = true;
 
     private static final long UPDATE_TIMEOUT_MILLIS = 5000;
+
     /** @hide */
     public static final String KEY_INITIALIZATION_STATUS = "initialization_status";
 
@@ -388,6 +389,14 @@
          */
         public void onDetected(@NonNull HotwordDetectedResult result) {
             requireNonNull(result);
+            final PersistableBundle persistableBundle = result.getExtras();
+            if (!persistableBundle.isEmpty() && HotwordDetectedResult.getParcelableSize(
+                    persistableBundle) > HotwordDetectedResult.getMaxBundleSize()) {
+                throw new IllegalArgumentException(
+                        "The bundle size of result is larger than max bundle size ("
+                                + HotwordDetectedResult.getMaxBundleSize()
+                                + ") of HotwordDetectedResult");
+            }
             try {
                 mRemoteCallback.onDetected(result);
             } catch (RemoteException e) {
diff --git a/core/java/android/view/CrossWindowBlurListeners.java b/core/java/android/view/CrossWindowBlurListeners.java
index e307b96..761a2b8 100644
--- a/core/java/android/view/CrossWindowBlurListeners.java
+++ b/core/java/android/view/CrossWindowBlurListeners.java
@@ -73,14 +73,14 @@
         return instance;
     }
 
-    boolean isCrossWindowBlurEnabled() {
+    public boolean isCrossWindowBlurEnabled() {
         synchronized (sLock) {
             attachInternalListenerIfNeededLocked();
             return mCrossWindowBlurEnabled;
         }
     }
 
-    void addListener(@NonNull @CallbackExecutor Executor executor,
+    public void addListener(@NonNull @CallbackExecutor Executor executor,
             @NonNull Consumer<Boolean> listener) {
         Preconditions.checkNotNull(listener, "listener cannot be null");
         Preconditions.checkNotNull(executor, "executor cannot be null");
@@ -94,7 +94,7 @@
     }
 
 
-    void removeListener(Consumer<Boolean> listener) {
+    public void removeListener(Consumer<Boolean> listener) {
         Preconditions.checkNotNull(listener, "listener cannot be null");
 
         synchronized (sLock) {
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 85ff93b..1506ee4 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -48,6 +48,7 @@
     private Insets mInsetsHint;
 
     private boolean mSkipAnimationOnce;
+    private int mParcelableFlags;
 
     public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash,
             Point surfacePosition, Insets insetsHint) {
@@ -132,6 +133,10 @@
         return result;
     }
 
+    public void setParcelableFlags(int parcelableFlags) {
+        mParcelableFlags = parcelableFlags;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -140,9 +145,9 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mType);
-        dest.writeTypedObject(mLeash, 0 /* parcelableFlags */);
-        dest.writeTypedObject(mSurfacePosition, 0 /* parcelableFlags */);
-        dest.writeTypedObject(mInsetsHint, 0 /* parcelableFlags */);
+        dest.writeTypedObject(mLeash, mParcelableFlags);
+        dest.writeTypedObject(mSurfacePosition, mParcelableFlags);
+        dest.writeTypedObject(mInsetsHint, mParcelableFlags);
         dest.writeBoolean(mSkipAnimationOnce);
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 573ae99..210f10c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5290,7 +5290,16 @@
                     // b) When loosing control, controller can restore server state by taking last
                     // dispatched state as truth.
                     mInsetsController.onStateChanged((InsetsState) args.arg1);
-                    mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2);
+                    InsetsSourceControl[] controls = (InsetsSourceControl[]) args.arg2;
+                    if (mAdded) {
+                        mInsetsController.onControlsChanged(controls);
+                    } else if (controls != null) {
+                        for (InsetsSourceControl control : controls) {
+                            if (control != null) {
+                                control.release(SurfaceControl::release);
+                            }
+                        }
+                    }
                     args.recycle();
                     break;
                 }
@@ -8136,6 +8145,10 @@
                 }
             }
 
+            // If our window is removed, we might not get notified about losing control.
+            // Invoking this can release the leashes as soon as possible instead of relying on GC.
+            mInsetsController.onControlsChanged(null);
+
             mAdded = false;
         }
         WindowManagerGlobal.getInstance().doRemoveView(this);
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index 10ae691..ce6d034 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -286,6 +286,15 @@
         return this;
     }
 
+    boolean hasSameComposingSpan(@NonNull ContentCaptureEvent other) {
+        return mComposingStart == other.mComposingStart && mComposingEnd == other.mComposingEnd;
+    }
+
+    boolean hasSameSelectionSpan(@NonNull ContentCaptureEvent other) {
+        return mSelectionStartIndex == other.mSelectionStartIndex
+                && mSelectionEndIndex == other.mSelectionEndIndex;
+    }
+
     private int getComposingStart() {
         return mComposingStart;
     }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index bcb9142..7ec9d34 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -368,7 +368,10 @@
                     final CharSequence lastText = lastEvent.getText();
                     final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
                             && !TextUtils.isEmpty(text);
-                    boolean equalContent = TextUtils.equals(lastText, text);
+                    boolean equalContent =
+                            TextUtils.equals(lastText, text)
+                            && lastEvent.hasSameComposingSpan(event)
+                            && lastEvent.hasSameSelectionSpan(event);
                     if (equalContent) {
                         addEvent = false;
                     } else if (bothNonEmpty) {
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index bdd1206..c4540b0 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -163,6 +163,17 @@
     }
 
     /**
+     * Called after only the composing region is modified (so it isn't called if the text also
+     * changes).
+     * <p>
+     * Default implementation does nothing.
+     *
+     * @hide
+     */
+    public void endComposingRegionEditInternal() {
+    }
+
+    /**
      * Default implementation calls {@link #finishComposingText()} and
      * {@code setImeConsumesInput(false)}.
      */
@@ -468,6 +479,7 @@
             // Note: sendCurrentText does nothing unless mFallbackMode is set
             sendCurrentText();
             endBatchEdit();
+            endComposingRegionEditInternal();
         }
         return true;
     }
@@ -734,6 +746,7 @@
             // Note: sendCurrentText does nothing unless mFallbackMode is set
             sendCurrentText();
             endBatchEdit();
+            endComposingRegionEditInternal();
         }
         return true;
     }
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 5ac878d..592993c 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -424,7 +424,7 @@
                     if (callback == null) {
                         if (view instanceof TextView) {
                             // developer doesn't provide their override, we set the default TextView
-                            // implememtation.
+                            // implementation.
                             callback = new TextViewTranslationCallback();
                             view.setViewTranslationCallback(callback);
                         } else {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3c4fd5e..37374ef 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -129,7 +129,6 @@
 import android.text.method.TimeKeyListener;
 import android.text.method.TransformationMethod;
 import android.text.method.TransformationMethod2;
-import android.text.method.TranslationTransformationMethod;
 import android.text.method.WordIterator;
 import android.text.style.CharacterStyle;
 import android.text.style.ClickableSpan;
@@ -199,7 +198,6 @@
 import android.view.translation.UiTranslationController;
 import android.view.translation.ViewTranslationCallback;
 import android.view.translation.ViewTranslationRequest;
-import android.view.translation.ViewTranslationResponse;
 import android.widget.RemoteViews.RemoteView;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -10832,11 +10830,19 @@
             }
         }
 
+        notifyContentCaptureTextChanged();
+    }
+
+    /**
+     * Notifies the ContentCapture service that the text of the view has changed (only if
+     * ContentCapture has been notified of this view's existence already).
+     *
+     * @hide
+     */
+    public void notifyContentCaptureTextChanged() {
         // TODO(b/121045053): should use a flag / boolean to keep status of SHOWN / HIDDEN instead
         // of using isLaidout(), so it's not called in cases where it's laid out but a
         // notifyAppeared was not sent.
-
-        // ContentCapture
         if (isLaidOut() && isImportantForContentCapture() && getNotifiedContentCaptureAppeared()) {
             final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
             if (cm != null && cm.isContentCaptureEnabled()) {
@@ -13925,8 +13931,8 @@
                     Log.w(LOG_TAG, "Cannot create translation request. editable = "
                             + isTextEditable() + ", isPassword = " + isPassword + ", selectable = "
                             + isTextSelectable());
-                    return;
                 }
+                return;
             }
             // TODO(b/176488462): apply the view's important for translation
             requestBuilder.setValue(ViewTranslationRequest.ID_TEXT,
@@ -13938,33 +13944,4 @@
         }
         requestsCollector.accept(requestBuilder.build());
     }
-
-    /**
-     *
-     * Called when the content from {@link #onCreateViewTranslationRequest} had been translated by
-     * the TranslationService. The default implementation will replace the current
-     * {@link TransformationMethod} to transform the original text to the translated text display.
-     *
-     * @param response a {@link ViewTranslationResponse} that contains the translated information
-     * which can be shown in the view.
-     */
-    @Override
-    public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) {
-        // set ViewTranslationResponse
-        super.onViewTranslationResponse(response);
-        // TODO(b/178353965): move to ViewTranslationCallback.onShow()
-        ViewTranslationCallback callback = getViewTranslationCallback();
-        if (callback instanceof TextViewTranslationCallback) {
-            TextViewTranslationCallback textViewDefaultCallback =
-                    (TextViewTranslationCallback) callback;
-            TranslationTransformationMethod oldTranslationMethod =
-                    textViewDefaultCallback.getTranslationTransformation();
-            TransformationMethod originalTranslationMethod = oldTranslationMethod != null
-                    ? oldTranslationMethod.getOriginalTransformationMethod() : mTransformation;
-            TranslationTransformationMethod newTranslationMethod =
-                    new TranslationTransformationMethod(response, originalTranslationMethod);
-            // TODO(b/178353965): well-handle setTransformationMethod.
-            textViewDefaultCallback.setTranslationTransformation(newTranslationMethod);
-        }
-    }
 }
diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java
index a7d5ee4..e1b04f8 100644
--- a/core/java/android/widget/TextViewTranslationCallback.java
+++ b/core/java/android/widget/TextViewTranslationCallback.java
@@ -56,26 +56,6 @@
 
     private CharSequence mContentDescription;
 
-    /**
-     * Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the
-     * view that provides the translatable information by {@link View#createTranslationRequest} and
-     * sent by the platform.
-     */
-    void setTranslationTransformation(TranslationTransformationMethod method) {
-        if (method == null) {
-            if (DEBUG) {
-                Log.w(TAG, "setTranslationTransformation: should not set null "
-                        + "TranslationTransformationMethod");
-            }
-            return;
-        }
-        mTranslationTransformation = method;
-    }
-
-    TranslationTransformationMethod getTranslationTransformation() {
-        return mTranslationTransformation;
-    }
-
     private void clearTranslationTransformation() {
         if (DEBUG) {
             Log.v(TAG, "clearTranslationTransformation: " + mTranslationTransformation);
@@ -88,34 +68,33 @@
      */
     @Override
     public boolean onShowTranslation(@NonNull View view) {
-        if (view.getViewTranslationResponse() == null) {
-            Log.wtf(TAG, "onShowTranslation() shouldn't be called before "
+        ViewTranslationResponse response = view.getViewTranslationResponse();
+        if (response == null) {
+            Log.e(TAG, "onShowTranslation() shouldn't be called before "
                     + "onViewTranslationResponse().");
             return false;
         }
-        if (mTranslationTransformation != null) {
-            final TransformationMethod transformation = mTranslationTransformation;
-            runWithAnimation(
-                    (TextView) view,
-                    () -> {
-                        mIsShowingTranslation = true;
-                        ((TextView) view).setTransformationMethod(transformation);
-                    });
-            ViewTranslationResponse response = view.getViewTranslationResponse();
-            if (response.getKeys().contains(ViewTranslationRequest.ID_CONTENT_DESCRIPTION)) {
-                CharSequence translatedContentDescription =
-                        response.getValue(ViewTranslationRequest.ID_CONTENT_DESCRIPTION).getText();
-                if (!TextUtils.isEmpty(translatedContentDescription)) {
-                    mContentDescription = view.getContentDescription();
-                    view.setContentDescription(translatedContentDescription);
-                }
+        if (mTranslationTransformation == null) {
+            TransformationMethod originalTranslationMethod =
+                    ((TextView) view).getTransformationMethod();
+            mTranslationTransformation = new TranslationTransformationMethod(response,
+                    originalTranslationMethod);
+        }
+        final TransformationMethod transformation = mTranslationTransformation;
+        runWithAnimation(
+                (TextView) view,
+                () -> {
+                    mIsShowingTranslation = true;
+                    // TODO(b/178353965): well-handle setTransformationMethod.
+                    ((TextView) view).setTransformationMethod(transformation);
+                });
+        if (response.getKeys().contains(ViewTranslationRequest.ID_CONTENT_DESCRIPTION)) {
+            CharSequence translatedContentDescription =
+                    response.getValue(ViewTranslationRequest.ID_CONTENT_DESCRIPTION).getText();
+            if (!TextUtils.isEmpty(translatedContentDescription)) {
+                mContentDescription = view.getContentDescription();
+                view.setContentDescription(translatedContentDescription);
             }
-        } else {
-            if (DEBUG) {
-                // TODO(b/182433547): remove before S release
-                Log.w(TAG, "onShowTranslation(): no translated text.");
-            }
-            return false;
         }
         return true;
     }
@@ -126,7 +105,7 @@
     @Override
     public boolean onHideTranslation(@NonNull View view) {
         if (view.getViewTranslationResponse() == null) {
-            Log.wtf(TAG, "onHideTranslation() shouldn't be called before "
+            Log.e(TAG, "onHideTranslation() shouldn't be called before "
                     + "onViewTranslationResponse().");
             return false;
         }
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 4a3bf91..148986a 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -292,6 +292,7 @@
 
         private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
             final SurfaceView surfaceView = new SurfaceView(view.getContext());
+            surfaceView.setPadding(0, 0, 0, 0);
             if (mSurfacePackage == null) {
                 if (DEBUG) {
                     Log.d(TAG,
diff --git a/core/java/com/android/internal/os/AppZygoteInit.java b/core/java/com/android/internal/os/AppZygoteInit.java
index 0e83e41..f925afc 100644
--- a/core/java/com/android/internal/os/AppZygoteInit.java
+++ b/core/java/com/android/internal/os/AppZygoteInit.java
@@ -91,7 +91,9 @@
                     } else {
                         Constructor<?> ctor = cl.getConstructor();
                         ZygotePreload preloadObject = (ZygotePreload) ctor.newInstance();
+                        Zygote.markOpenedFilesBeforePreload();
                         preloadObject.doPreload(appInfo);
+                        Zygote.allowFilesOpenedByPreload();
                     }
                 } catch (ReflectiveOperationException e) {
                     Log.e(TAG, "AppZygote application preload failed for "
diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java
index 4f2f973b..dfd561a 100644
--- a/core/java/com/android/internal/os/BatterySipper.java
+++ b/core/java/com/android/internal/os/BatterySipper.java
@@ -23,7 +23,10 @@
 
 /**
  * Contains power usage of an application, system service, or hardware type.
+ *
+ * @deprecated Please use BatteryStatsManager.getBatteryUsageStats instead.
  */
+@Deprecated
 public class BatterySipper implements Comparable<BatterySipper> {
     @UnsupportedAppUsage
     public int userId;
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index b20f50d..608782a 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -59,7 +59,10 @@
  *
  * The caller must initialize this class as soon as activity object is ready to use (for example, in
  * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy().
+ *
+ * @deprecated Please use BatteryStatsManager.getBatteryUsageStats instead.
  */
+@Deprecated
 public class BatteryStatsHelper {
     static final boolean DEBUG = false;
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 945a6ab..dab3e9f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -12141,6 +12141,15 @@
                 }
             }
         }
+
+        void reset() {
+            idleTimeMs = 0;
+            rxTimeMs = 0;
+            txTimeMs = 0;
+            energy = 0;
+            uidRxBytes.clear();
+            uidTxBytes.clear();
+        }
     }
 
     private final BluetoothActivityInfoCache mLastBluetoothActivityInfo
@@ -12167,6 +12176,15 @@
 
         mHasBluetoothReporting = true;
 
+        if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs
+                || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs
+                || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs
+                || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) {
+            // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash.
+            // Reset the preserved previous snapshot in order to restart accumulating deltas.
+            mLastBluetoothActivityInfo.reset();
+        }
+
         final long rxTimeMs =
                 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs;
         final long txTimeMs =
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 0c9dded..e4e28a9 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -500,6 +500,36 @@
     }
 
     /**
+     * Scans file descriptors in /proc/self/fd/, stores their metadata from readlink(2)/stat(2) when
+     * available. Saves this information in a global on native side, to be used by subsequent call
+     * to allowFilesOpenedByPreload(). Fatally fails if the FDs are of unsupported type and are not
+     * explicitly allowed. Ignores repeated invocations.
+     *
+     * Inspecting the FDs is more permissive than in forkAndSpecialize() because preload is invoked
+     * earlier and hence needs to allow a few open sockets. The checks in forkAndSpecialize()
+     * enforce that these sockets are closed when forking.
+     */
+    static void markOpenedFilesBeforePreload() {
+        nativeMarkOpenedFilesBeforePreload();
+    }
+
+    private static native void nativeMarkOpenedFilesBeforePreload();
+
+    /**
+     * By scanning /proc/self/fd/ determines file descriptor numbers in this process opened since
+     * the first call to markOpenedFilesBeforePreload(). These FDs are treated as 'owned' by the
+     * custom preload of the App Zygote - the app is responsible for not sharing data with its other
+     * processes using these FDs, including by lseek(2). File descriptor types and file names are
+     * not checked. Changes in FDs recorded by markOpenedFilesBeforePreload() are not expected and
+     * kill the current process.
+     */
+    static void allowFilesOpenedByPreload() {
+        nativeAllowFilesOpenedByPreload();
+    }
+
+    private static native void nativeAllowFilesOpenedByPreload();
+
+    /**
      * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
      * @param uidGidMin The smallest allowed uid/gid
      * @param uidGidMax The largest allowed uid/gid
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 1a23cc1..134b158 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -70,12 +70,12 @@
 import android.transition.TransitionManager;
 import android.transition.TransitionSet;
 import android.util.AndroidRuntimeException;
-import android.view.AttachedSurfaceControl;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
 import android.util.TypedValue;
+import android.view.AttachedSurfaceControl;
 import android.view.ContextThemeWrapper;
 import android.view.CrossWindowBlurListeners;
 import android.view.Gravity;
@@ -3148,7 +3148,6 @@
         if (cb == null || isDestroyed()) {
             result = false;
         } else {
-            sendCloseSystemWindows("search");
             int deviceId = event.getDeviceId();
             SearchEvent searchEvent = null;
             if (deviceId != 0) {
diff --git a/core/java/com/android/internal/util/function/DodecConsumer.java b/core/java/com/android/internal/util/function/DodecConsumer.java
new file mode 100644
index 0000000..b4d2fb9
--- /dev/null
+++ b/core/java/com/android/internal/util/function/DodecConsumer.java
@@ -0,0 +1,29 @@
+/*
+ * 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.function;
+
+import java.util.function.Consumer;
+
+
+/**
+ * A 12-argument {@link Consumer}
+ *
+ * @hide
+ */
+public interface DodecConsumer<A, B, C, D, E, F, G, H, I, J, K, L> {
+    void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l);
+}
diff --git a/core/java/com/android/internal/util/function/DodecFunction.java b/core/java/com/android/internal/util/function/DodecFunction.java
new file mode 100644
index 0000000..178b2c1
--- /dev/null
+++ b/core/java/com/android/internal/util/function/DodecFunction.java
@@ -0,0 +1,28 @@
+/*
+ * 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.function;
+
+import java.util.function.Function;
+
+/**
+ * A 12-argument {@link Function}
+ *
+ * @hide
+ */
+public interface DodecFunction<A, B, C, D, E, F, G, H, I, J, K, L, R> {
+    R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l);
+}
diff --git a/core/java/com/android/internal/util/function/DodecPredicate.java b/core/java/com/android/internal/util/function/DodecPredicate.java
new file mode 100644
index 0000000..d3a2b85
--- /dev/null
+++ b/core/java/com/android/internal/util/function/DodecPredicate.java
@@ -0,0 +1,28 @@
+/*
+ * 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.function;
+
+import java.util.function.Predicate;
+
+/**
+ * A 12-argument {@link Predicate}
+ *
+ * @hide
+ */
+public interface DodecPredicate<A, B, C, D, E, F, G, H, I, J, K, L> {
+    boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l);
+}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
index a60cc0f..f073c1c0 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
@@ -23,6 +23,8 @@
 
 import com.android.internal.util.function.DecConsumer;
 import com.android.internal.util.function.DecFunction;
+import com.android.internal.util.function.DodecConsumer;
+import com.android.internal.util.function.DodecFunction;
 import com.android.internal.util.function.HeptConsumer;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HexConsumer;
@@ -188,7 +190,7 @@
             A arg1) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -205,7 +207,7 @@
             A arg1) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -222,7 +224,7 @@
             A arg1) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -253,7 +255,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -273,7 +275,7 @@
             A arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -291,7 +293,7 @@
             A arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -309,7 +311,7 @@
             A arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -327,7 +329,7 @@
             ArgumentPlaceholder<A> arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -345,7 +347,7 @@
             ArgumentPlaceholder<A> arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -364,7 +366,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -384,7 +386,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -405,7 +407,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4, E arg5) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 5, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, arg5, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -423,7 +425,7 @@
             ArgumentPlaceholder<A> arg1, B arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -441,7 +443,7 @@
             A arg1, ArgumentPlaceholder<B> arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -459,7 +461,7 @@
             A arg1, ArgumentPlaceholder<B> arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -477,7 +479,7 @@
             A arg1, ArgumentPlaceholder<B> arg2) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -509,7 +511,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -530,7 +532,7 @@
             A arg1, B arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -549,7 +551,7 @@
             A arg1, B arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -568,7 +570,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -587,7 +589,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -606,7 +608,7 @@
             A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -625,7 +627,7 @@
             A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -644,7 +646,7 @@
             A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -663,7 +665,7 @@
             A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -696,7 +698,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -718,7 +720,7 @@
             A arg1, B arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -738,7 +740,7 @@
             A arg1, B arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -758,7 +760,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -778,7 +780,7 @@
             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -798,7 +800,7 @@
             A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -818,7 +820,7 @@
             A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -838,7 +840,7 @@
             A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -858,7 +860,7 @@
             A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -878,7 +880,7 @@
             A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -898,7 +900,7 @@
             A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -932,7 +934,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -955,7 +957,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -976,7 +978,7 @@
                     function, A arg1, B arg2, C arg3, D arg4, E arg5) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1012,7 +1014,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1036,7 +1038,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1058,7 +1060,7 @@
                     ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1095,7 +1097,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1120,7 +1122,7 @@
                     ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1144,7 +1146,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1182,7 +1184,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1209,7 +1211,7 @@
             H arg8) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1234,7 +1236,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 8, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -1274,7 +1276,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                    null, null, null);
+                    null, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1302,7 +1304,7 @@
             E arg5, F arg6, G arg7, H arg8, I arg9) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, null, null);
+                arg9, null, null, null);
     }
 
     /**
@@ -1328,7 +1330,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 9, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, null, null);
+                arg9, null, null, null);
     }
 
     /**
@@ -1369,7 +1371,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                    arg9, null, null);
+                    arg9, null, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1398,7 +1400,7 @@
             D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, arg10, null);
+                arg9, arg10, null, null);
     }
 
     /**
@@ -1425,7 +1427,7 @@
             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 10, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, arg10, null);
+                arg9, arg10, null, null);
     }
 
     /**
@@ -1467,7 +1469,7 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
-                    arg8, arg9, arg10, null);
+                    arg8, arg9, arg10, null, null);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
@@ -1498,7 +1500,7 @@
             C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, arg10, arg11);
+                arg9, arg10, arg11, null);
     }
 
     /**
@@ -1528,7 +1530,7 @@
             K arg11) {
         return acquire(PooledLambdaImpl.sPool,
                 function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
-                arg9, arg10, arg11);
+                arg9, arg10, arg11, null);
     }
 
     /**
@@ -1571,7 +1573,118 @@
         synchronized (Message.sPoolSync) {
             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                     function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
-                    arg8, arg9, arg10, arg11);
+                    arg8, arg9, arg10, arg11, null);
+            return Message.obtain().setCallback(callback.recycleOnUse());
+        }
+    }
+
+    /**
+     * {@link PooledRunnable} factory
+     *
+     * @param function non-capturing lambda(typically an unbounded method reference)
+     *                 to be invoked on call
+     * @param arg1 parameter supplied to {@code function} on call
+     * @param arg2 parameter supplied to {@code function} on call
+     * @param arg3 parameter supplied to {@code function} on call
+     * @param arg4 parameter supplied to {@code function} on call
+     * @param arg5 parameter supplied to {@code function} on call
+     * @param arg6 parameter supplied to {@code function} on call
+     * @param arg7 parameter supplied to {@code function} on call
+     * @param arg8 parameter supplied to {@code function} on call
+     * @param arg9 parameter supplied to {@code function} on call
+     * @param arg10 parameter supplied to {@code function} on call
+     * @param arg11 parameter supplied to {@code function} on call
+     * @param arg12 parameter supplied to {@code function} on call
+     * @return a {@link PooledRunnable}, equivalent to lambda:
+     *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+     *         arg11, arg12) }
+     */
+    static <A, B, C, D, E, F, G, H, I, J, K, L> PooledRunnable obtainRunnable(
+            DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+                                ? super G, ? super H, ? super I, ? super J, ? super K,
+                                ? super L> function,
+            A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
+            K arg11, L arg12) {
+        return acquire(PooledLambdaImpl.sPool,
+                function, 12, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+                arg9, arg10, arg11, arg12);
+    }
+
+    /**
+     * {@link PooledSupplier} factory
+     *
+     * @param function non-capturing lambda(typically an unbounded method reference)
+     *                 to be invoked on call
+     * @param arg1 parameter supplied to {@code function} on call
+     * @param arg2 parameter supplied to {@code function} on call
+     * @param arg3 parameter supplied to {@code function} on call
+     * @param arg4 parameter supplied to {@code function} on call
+     * @param arg5 parameter supplied to {@code function} on call
+     * @param arg6 parameter supplied to {@code function} on call
+     * @param arg7 parameter supplied to {@code function} on call
+     * @param arg8 parameter supplied to {@code function} on call
+     * @param arg9 parameter supplied to {@code function} on call
+     * @param arg10 parameter supplied to {@code function} on call
+     * @param arg11 parameter supplied to {@code function} on call
+     * @param arg12 parameter supplied to {@code function} on call
+     * @return a {@link PooledSupplier}, equivalent to lambda:
+     *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+     *         arg11) }
+     */
+    static <A, B, C, D, E, F, G, H, I, J, K, L, R> PooledSupplier<R> obtainSupplier(
+            DodecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+                                ? super G, ? super H, ? super I, ? super J, ? super K, ? extends L,
+                                ? extends R> function,
+            A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
+            K arg11, L arg12) {
+        return acquire(PooledLambdaImpl.sPool,
+                function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+                arg9, arg10, arg11, arg12);
+    }
+
+    /**
+     * Factory of {@link Message}s that contain an
+     * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+     * {@link Message#getCallback internal callback}.
+     *
+     * The callback is equivalent to one obtainable via
+     * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+     *
+     * Note that using this method with {@link android.os.Handler#handleMessage}
+     * is more efficient than the alternative of {@link android.os.Handler#post}
+     * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+     * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+     *
+     * You may optionally set a {@link Message#what} for the message if you want to be
+     * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+     * there's no need to do so
+     *
+     * @param function non-capturing lambda(typically an unbounded method reference)
+     *                 to be invoked on call
+     * @param arg1 parameter supplied to {@code function} on call
+     * @param arg2 parameter supplied to {@code function} on call
+     * @param arg3 parameter supplied to {@code function} on call
+     * @param arg4 parameter supplied to {@code function} on call
+     * @param arg5 parameter supplied to {@code function} on call
+     * @param arg6 parameter supplied to {@code function} on call
+     * @param arg7 parameter supplied to {@code function} on call
+     * @param arg8 parameter supplied to {@code function} on call
+     * @param arg9 parameter supplied to {@code function} on call
+     * @param arg10 parameter supplied to {@code function} on call
+     * @param arg11 parameter supplied to {@code function} on call
+     * @param arg12 parameter supplied to {@code function} on call
+     * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+     * arg7, arg8, arg9, arg10, arg11) } when handled
+     */
+    static <A, B, C, D, E, F, G, H, I, J, K, L> Message obtainMessage(
+            DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+                    ? super G, ? super H, ? super I, ? super J, ? super K, ? super L> function,
+            A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
+            K arg11, L arg12) {
+        synchronized (Message.sPoolSync) {
+            PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+                    function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+                    arg8, arg9, arg10, arg11, arg12);
             return Message.obtain().setCallback(callback.recycleOnUse());
         }
     }
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index 1646a07..19f0816 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -28,6 +28,9 @@
 import com.android.internal.util.function.DecConsumer;
 import com.android.internal.util.function.DecFunction;
 import com.android.internal.util.function.DecPredicate;
+import com.android.internal.util.function.DodecConsumer;
+import com.android.internal.util.function.DodecFunction;
+import com.android.internal.util.function.DodecPredicate;
 import com.android.internal.util.function.HeptConsumer;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HeptPredicate;
@@ -458,6 +461,28 @@
                     }
                 }
             } break;
+
+            case 12: {
+                switch (returnType) {
+                    case LambdaType.ReturnType.VOID: {
+                        ((DodecConsumer) mFunc).accept(popArg(0), popArg(1),
+                                popArg(2), popArg(3), popArg(4), popArg(5),
+                                popArg(6), popArg(7), popArg(8), popArg(9), popArg(10), popArg(11));
+                        return null;
+                    }
+                    case LambdaType.ReturnType.BOOLEAN: {
+                        return (R) (Object) ((DodecPredicate) mFunc).test(popArg(0),
+                                popArg(1), popArg(2), popArg(3), popArg(4),
+                                popArg(5), popArg(6), popArg(7), popArg(8), popArg(9), popArg(10),
+                                popArg(11));
+                    }
+                    case LambdaType.ReturnType.OBJECT: {
+                        return (R) ((DodecFunction) mFunc).apply(popArg(0), popArg(1),
+                                popArg(2), popArg(3), popArg(4), popArg(5),
+                                popArg(6), popArg(7), popArg(8), popArg(9), popArg(10), popArg(11));
+                    }
+                }
+            } break;
         }
         throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType));
     }
@@ -523,7 +548,8 @@
      */
     static <E extends PooledLambda> E acquire(Pool pool, Object func,
             int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c,
-            Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k) {
+            Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k,
+            Object l) {
         PooledLambdaImpl r = acquire(pool);
         if (DEBUG) {
             Log.i(LOG_TAG,
@@ -543,6 +569,7 @@
                             + ", i = " + i
                             + ", j = " + j
                             + ", k = " + k
+                            + ", l = " + l
                             + ")");
         }
         r.mFunc = Objects.requireNonNull(func);
@@ -560,6 +587,7 @@
         setIfInBounds(r.mArgs, 8, i);
         setIfInBounds(r.mArgs, 9, j);
         setIfInBounds(r.mArgs, 10, k);
+        setIfInBounds(r.mArgs, 11, l);
         return (E) r;
     }
 
diff --git a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
index 8aa2d57..9e09006 100644
--- a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
+++ b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
@@ -198,12 +198,9 @@
         private static final float LIGHT_RADIUS_DP = 800;
         private static final String TAG = "ViewRenderer";
 
-        private HardwareRenderer mRenderer;
-        private RenderNode mCaptureRenderNode;
-        private final RectF mTempRectF = new RectF();
-        private final Rect mSourceRect = new Rect();
+        private final HardwareRenderer mRenderer;
+        private final RenderNode mCaptureRenderNode;
         private final Rect mTempRect = new Rect();
-        private final Matrix mTempMatrix = new Matrix();
         private final int[] mTempLocation = new int[2];
         private long mLastRenderedSourceDrawingId = -1;
         private Surface mSurface;
@@ -313,11 +310,9 @@
         }
 
         private void transformToRoot(View local, Rect localRect, Rect outRect) {
-            mTempMatrix.reset();
-            local.transformMatrixToGlobal(mTempMatrix);
-            mTempRectF.set(localRect);
-            mTempMatrix.mapRect(mTempRectF);
-            mTempRectF.round(outRect);
+            local.getLocationInWindow(mTempLocation);
+            outRect.set(localRect);
+            outRect.offset(mTempLocation[0], mTempLocation[1]);
         }
 
         public void setColorMode(@ColorMode int colorMode) {
diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java
index 4a70f74..299cbe1 100644
--- a/core/java/com/android/internal/widget/CachingIconView.java
+++ b/core/java/com/android/internal/widget/CachingIconView.java
@@ -257,7 +257,7 @@
         boolean hasColor = color != ColoredIconHelper.COLOR_INVALID;
         if (background == null) {
             // This is the pre-S style -- colored icon with no background.
-            if (hasColor) {
+            if (hasColor && icon != null) {
                 icon.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
             }
         } else {
@@ -265,7 +265,9 @@
             // colorize the icon itself with the background color, creating an inverted effect.
             if (hasColor) {
                 background.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-                icon.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
+                if (icon != null) {
+                    icon.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
+                }
             } else {
                 background.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
             }
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 3d054a5..02ffe8c 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -99,6 +99,12 @@
     }
 
     @Override
+    public void endComposingRegionEditInternal() {
+        // The ContentCapture service is interested in Composing-state changes.
+        mTextView.notifyContentCaptureTextChanged();
+    }
+
+    @Override
     public void closeConnection() {
         super.closeConnection();
         synchronized(this) {
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 73c5460..3f756d7 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -1524,7 +1524,9 @@
             if (virtualViewId != ExploreByTouchHelper.INVALID_ID) {
                 int row = (virtualViewId - VIRTUAL_BASE_VIEW_ID) / 3;
                 int col = (virtualViewId - VIRTUAL_BASE_VIEW_ID) % 3;
-                return !mPatternDrawLookup[row][col];
+                if (row < 3) {
+                    return !mPatternDrawLookup[row][col];
+                }
             }
             return false;
         }
@@ -1570,7 +1572,6 @@
             final Rect bounds = mTempRect;
             final int row = ordinal / 3;
             final int col = ordinal % 3;
-            final CellState cell = mCellStates[row][col];
             float centerX = getCenterXForColumn(col);
             float centerY = getCenterYForRow(row);
             float cellheight = mSquareHeight * mHitFactor * 0.5f;
diff --git a/core/java/com/android/server/AppWidgetBackupBridge.java b/core/java/com/android/server/AppWidgetBackupBridge.java
index 7d82d35..8e834a8 100644
--- a/core/java/com/android/server/AppWidgetBackupBridge.java
+++ b/core/java/com/android/server/AppWidgetBackupBridge.java
@@ -47,9 +47,9 @@
                 : null;
     }
 
-    public static void restoreStarting(int userId) {
+    public static void systemRestoreStarting(int userId) {
         if (sAppWidgetService != null) {
-            sAppWidgetService.restoreStarting(userId);
+            sAppWidgetService.systemRestoreStarting(userId);
         }
     }
 
@@ -59,9 +59,9 @@
         }
     }
 
-    public static void restoreFinished(int userId) {
+    public static void systemRestoreFinished(int userId) {
         if (sAppWidgetService != null) {
-            sAppWidgetService.restoreFinished(userId);
+            sAppWidgetService.systemRestoreFinished(userId);
         }
     }
 }
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 6976ace..a8dcbaf 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -86,6 +86,7 @@
     // and "allow-ignore-location-settings".
     private static final int ALLOW_OVERRIDE_APP_RESTRICTIONS = 0x100;
     private static final int ALLOW_IMPLICIT_BROADCASTS = 0x200;
+    private static final int ALLOW_VENDOR_APEX = 0x400;
     private static final int ALLOW_ALL = ~0;
 
     // property for runtime configuration differentiation
@@ -240,7 +241,7 @@
 
     private final ArraySet<String> mRollbackWhitelistedPackages = new ArraySet<>();
     private final ArraySet<String> mWhitelistedStagedInstallers = new ArraySet<>();
-    private final ArraySet<String> mAllowedPartnerApexes = new ArraySet<>();
+    private final ArraySet<String> mAllowedVendorApexes = new ArraySet<>();
 
     /**
      * Map of system pre-defined, uniquely named actors; keys are namespace,
@@ -411,8 +412,8 @@
         return mWhitelistedStagedInstallers;
     }
 
-    public Set<String> getAllowedPartnerApexes() {
-        return mAllowedPartnerApexes;
+    public Set<String> getAllowedVendorApexes() {
+        return mAllowedVendorApexes;
     }
 
     public ArraySet<String> getAppDataIsolationWhitelistedApps() {
@@ -489,7 +490,7 @@
 
         // Vendors are only allowed to customize these
         int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS
-                | ALLOW_ASSOCIATIONS;
+                | ALLOW_ASSOCIATIONS | ALLOW_VENDOR_APEX;
         if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.O_MR1) {
             // For backward compatibility
             vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
@@ -530,7 +531,8 @@
         }
 
         // Allow OEM to customize these
-        int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS;
+        int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS
+                | ALLOW_VENDOR_APEX;
         readPermissions(Environment.buildPath(
                 Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
         readPermissions(Environment.buildPath(
@@ -541,7 +543,8 @@
         // the use of hidden APIs from the product partition.
         int productPermissionFlag = ALLOW_FEATURES | ALLOW_LIBS | ALLOW_PERMISSIONS
                 | ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS | ALLOW_HIDDENAPI_WHITELISTING
-                | ALLOW_ASSOCIATIONS | ALLOW_OVERRIDE_APP_RESTRICTIONS | ALLOW_IMPLICIT_BROADCASTS;
+                | ALLOW_ASSOCIATIONS | ALLOW_OVERRIDE_APP_RESTRICTIONS | ALLOW_IMPLICIT_BROADCASTS
+                | ALLOW_VENDOR_APEX;
         if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) {
             // TODO(b/157393157): This must check product interface enforcement instead of
             // DEVICE_INITIAL_SDK_INT for the devices without product interface enforcement.
@@ -668,6 +671,7 @@
                     (permissionFlag & ALLOW_OVERRIDE_APP_RESTRICTIONS) != 0;
             final boolean allowImplicitBroadcasts = (permissionFlag & ALLOW_IMPLICIT_BROADCASTS)
                     != 0;
+            final boolean allowVendorApex = (permissionFlag & ALLOW_VENDOR_APEX) != 0;
             while (true) {
                 XmlUtils.nextElement(parser);
                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
@@ -1217,15 +1221,14 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
-                    case "allowed-partner-apex": {
-                        // TODO(b/189274479): should this be allowOemPermissions instead?
-                        if (allowAppConfigs) {
+                    case "allowed-vendor-apex": {
+                        if (allowVendorApex) {
                             String pkgName = parser.getAttributeValue(null, "package");
                             if (pkgName == null) {
                                 Slog.w(TAG, "<" + name + "> without package in " + permFile
                                         + " at " + parser.getPositionDescription());
                             } else {
-                                mAllowedPartnerApexes.add(pkgName);
+                                mAllowedVendorApexes.add(pkgName);
                             }
                         } else {
                             logNotAllowedInPartition(name, permFile, parser);
diff --git a/core/java/com/android/server/WidgetBackupProvider.java b/core/java/com/android/server/WidgetBackupProvider.java
index a2efbdd..5453c4d 100644
--- a/core/java/com/android/server/WidgetBackupProvider.java
+++ b/core/java/com/android/server/WidgetBackupProvider.java
@@ -28,7 +28,7 @@
 public interface WidgetBackupProvider {
     public List<String> getWidgetParticipants(int userId);
     public byte[] getWidgetState(String packageName, int userId);
-    public void restoreStarting(int userId);
+    public void systemRestoreStarting(int userId);
     public void restoreWidgetState(String packageName, byte[] restoredState, int userId);
-    public void restoreFinished(int userId);
+    public void systemRestoreFinished(int userId);
 }
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4a1a272..502849e 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -27,9 +27,11 @@
 #include <sys/types.h>
 #include <dirent.h>
 
+#include <algorithm>
 #include <array>
 #include <atomic>
 #include <functional>
+#include <iterator>
 #include <list>
 #include <optional>
 #include <sstream>
@@ -2005,6 +2007,9 @@
   __builtin_unreachable();
 }
 
+static std::set<int>* gPreloadFds = nullptr;
+static bool gPreloadFdsExtracted = false;
+
 // Utility routine to fork a process from the zygote.
 pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                          const std::vector<int>& fds_to_close,
@@ -2030,9 +2035,12 @@
   __android_log_close();
   AStatsSocket_close();
 
-  // If this is the first fork for this zygote, create the open FD table.  If
-  // it isn't, we just need to check whether the list of open files has changed
-  // (and it shouldn't in the normal case).
+  // If this is the first fork for this zygote, create the open FD table,
+  // verifying that files are of supported type and allowlisted.  Otherwise (not
+  // the first fork), check that the open files have not changed.  Newly open
+  // files are not expected, and will be disallowed in the future.  Currently
+  // they are allowed if they pass the same checks as in the
+  // FileDescriptorTable::Create() above.
   if (gOpenFdTable == nullptr) {
     gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
   } else {
@@ -2128,7 +2136,12 @@
         fds_to_ignore.push_back(gSystemServerSocketFd);
     }
 
-    pid_t pid = zygote::ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
+    if (gPreloadFds && gPreloadFdsExtracted) {
+        fds_to_ignore.insert(fds_to_ignore.end(), gPreloadFds->begin(), gPreloadFds->end());
+    }
+
+    pid_t pid = zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
+                                   true);
 
     if (pid == 0) {
         SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities,
@@ -2265,6 +2278,10 @@
       }
       fds_to_ignore.push_back(gSystemServerSocketFd);
   }
+  if (gPreloadFds && gPreloadFdsExtracted) {
+      fds_to_ignore.insert(fds_to_ignore.end(), gPreloadFds->begin(), gPreloadFds->end());
+  }
+
   return zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close,
                             fds_to_ignore, is_priority_fork == JNI_TRUE, purge);
 }
@@ -2568,6 +2585,35 @@
 #endif // defined(__aarch64__)
 }
 
+static void com_android_internal_os_Zygote_nativeMarkOpenedFilesBeforePreload(JNIEnv* env, jclass) {
+    // Ignore invocations when too early or too late.
+    if (gPreloadFds) {
+        return;
+    }
+
+    // App Zygote Preload starts soon. Save FDs remaining open.  After the
+    // preload finishes newly open files will be determined.
+    auto fail_fn = std::bind(zygote::ZygoteFailure, env, "zygote", nullptr, _1);
+    gPreloadFds = GetOpenFds(fail_fn).release();
+}
+
+static void com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload(JNIEnv* env, jclass) {
+    // Ignore invocations when too early or too late.
+    if (!gPreloadFds || gPreloadFdsExtracted) {
+        return;
+    }
+
+    // Find the newly open FDs, if any.
+    auto fail_fn = std::bind(zygote::ZygoteFailure, env, "zygote", nullptr, _1);
+    std::unique_ptr<std::set<int>> current_fds = GetOpenFds(fail_fn);
+    auto difference = std::make_unique<std::set<int>>();
+    std::set_difference(current_fds->begin(), current_fds->end(), gPreloadFds->begin(),
+                        gPreloadFds->end(), std::inserter(*difference, difference->end()));
+    delete gPreloadFds;
+    gPreloadFds = difference.release();
+    gPreloadFdsExtracted = true;
+}
+
 static const JNINativeMethod gMethods[] = {
         {"nativeForkAndSpecialize",
          "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
@@ -2616,6 +2662,10 @@
          (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers},
         {"nativeCurrentTaggingLevel", "()I",
          (void*)com_android_internal_os_Zygote_nativeCurrentTaggingLevel},
+        {"nativeMarkOpenedFilesBeforePreload", "()V",
+         (void*)com_android_internal_os_Zygote_nativeMarkOpenedFilesBeforePreload},
+        {"nativeAllowFilesOpenedByPreload", "()V",
+         (void*)com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload},
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 7fa627b..6f5cc53 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -52,7 +52,6 @@
 
 static const char kFdPath[] = "/proc/self/fd";
 
-// static
 FileDescriptorAllowlist* FileDescriptorAllowlist::Get() {
     if (instance_ == nullptr) {
         instance_ = new FileDescriptorAllowlist();
@@ -169,8 +168,8 @@
   // Create a FileDescriptorInfo for a given file descriptor.
   static FileDescriptorInfo* CreateFromFd(int fd, fail_fn_t fail_fn);
 
-  // Checks whether the file descriptor associated with this object
-  // refers to the same description.
+  // Checks whether the file descriptor associated with this object refers to
+  // the same description.
   bool RefersToSameFile() const;
 
   void ReopenOrDetach(fail_fn_t fail_fn) const;
@@ -185,8 +184,10 @@
   const bool is_sock;
 
  private:
+  // Constructs for sockets.
   explicit FileDescriptorInfo(int fd);
 
+  // Constructs for non-socket file descriptors.
   FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
                      int fd_flags, int fs_flags, off_t offset);
 
@@ -204,7 +205,6 @@
   DISALLOW_COPY_AND_ASSIGN(FileDescriptorInfo);
 };
 
-// static
 FileDescriptorInfo* FileDescriptorInfo::CreateFromFd(int fd, fail_fn_t fail_fn) {
   struct stat f_stat;
   // This should never happen; the zygote should always have the right set
@@ -465,42 +465,24 @@
   }
 }
 
-// static
+// TODO: Move the definitions here and eliminate the forward declarations. They
+// temporarily help making code reviews easier.
+static int ParseFd(dirent* dir_entry, int dir_fd);
+static std::unique_ptr<std::set<int>> GetOpenFdsIgnoring(const std::vector<int>& fds_to_ignore,
+                                                         fail_fn_t fail_fn);
+
 FileDescriptorTable* FileDescriptorTable::Create(const std::vector<int>& fds_to_ignore,
                                                  fail_fn_t fail_fn) {
-  DIR* proc_fd_dir = opendir(kFdPath);
-  if (proc_fd_dir == nullptr) {
-    fail_fn(std::string("Unable to open directory ").append(kFdPath));
-  }
-
-  int dir_fd = dirfd(proc_fd_dir);
-  dirent* dir_entry;
-
+  std::unique_ptr<std::set<int>> open_fds = GetOpenFdsIgnoring(fds_to_ignore, fail_fn);
   std::unordered_map<int, FileDescriptorInfo*> open_fd_map;
-  while ((dir_entry = readdir(proc_fd_dir)) != nullptr) {
-    const int fd = ParseFd(dir_entry, dir_fd);
-    if (fd == -1) {
-      continue;
-    }
-
-    if (std::find(fds_to_ignore.begin(), fds_to_ignore.end(), fd) != fds_to_ignore.end()) {
-      continue;
-    }
-
+  for (auto fd : *open_fds) {
     open_fd_map[fd] = FileDescriptorInfo::CreateFromFd(fd, fail_fn);
   }
-
-  if (closedir(proc_fd_dir) == -1) {
-    fail_fn("Unable to close directory");
-  }
-
   return new FileDescriptorTable(open_fd_map);
 }
 
-void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn) {
-  std::set<int> open_fds;
-
-  // First get the list of open descriptors.
+static std::unique_ptr<std::set<int>> GetOpenFdsIgnoring(const std::vector<int>& fds_to_ignore,
+                                                         fail_fn_t fail_fn) {
   DIR* proc_fd_dir = opendir(kFdPath);
   if (proc_fd_dir == nullptr) {
     fail_fn(android::base::StringPrintf("Unable to open directory %s: %s",
@@ -508,6 +490,7 @@
                                         strerror(errno)));
   }
 
+  auto result = std::make_unique<std::set<int>>();
   int dir_fd = dirfd(proc_fd_dir);
   dirent* dir_entry;
   while ((dir_entry = readdir(proc_fd_dir)) != nullptr) {
@@ -520,14 +503,26 @@
       continue;
     }
 
-    open_fds.insert(fd);
+    result->insert(fd);
   }
 
   if (closedir(proc_fd_dir) == -1) {
     fail_fn(android::base::StringPrintf("Unable to close directory: %s", strerror(errno)));
   }
+  return result;
+}
 
-  RestatInternal(open_fds, fail_fn);
+std::unique_ptr<std::set<int>> GetOpenFds(fail_fn_t fail_fn) {
+  const std::vector<int> nothing_to_ignore;
+  return GetOpenFdsIgnoring(nothing_to_ignore, fail_fn);
+}
+
+void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn) {
+  std::unique_ptr<std::set<int>> open_fds = GetOpenFdsIgnoring(fds_to_ignore, fail_fn);
+
+  // Check that the files did not change, and leave only newly opened FDs in
+  // |open_fds|.
+  RestatInternal(*open_fds, fail_fn);
 }
 
 // Reopens all file descriptors that are contained in the table.
@@ -548,6 +543,12 @@
     : open_fd_map_(map) {
 }
 
+FileDescriptorTable::~FileDescriptorTable() {
+    for (auto& it : open_fd_map_) {
+        delete it.second;
+    }
+}
+
 void FileDescriptorTable::RestatInternal(std::set<int>& open_fds, fail_fn_t fail_fn) {
   // ART creates a file through memfd for optimization purposes. We make sure
   // there is at most one being created.
@@ -618,8 +619,7 @@
   }
 }
 
-// static
-int FileDescriptorTable::ParseFd(dirent* dir_entry, int dir_fd) {
+static int ParseFd(dirent* dir_entry, int dir_fd) {
   char* end;
   const int fd = strtol(dir_entry->d_name, &end, 10);
   if ((*end) != '\0') {
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
index 14c318e..a28ebf1 100644
--- a/core/jni/fd_utils.h
+++ b/core/jni/fd_utils.h
@@ -69,6 +69,9 @@
     DISALLOW_COPY_AND_ASSIGN(FileDescriptorAllowlist);
 };
 
+// Returns the set of file descriptors currently open by the process.
+std::unique_ptr<std::set<int>> GetOpenFds(fail_fn_t fail_fn);
+
 // A FileDescriptorTable is a collection of FileDescriptorInfo objects
 // keyed by their FDs.
 class FileDescriptorTable {
@@ -79,6 +82,14 @@
   static FileDescriptorTable* Create(const std::vector<int>& fds_to_ignore,
                                      fail_fn_t fail_fn);
 
+  ~FileDescriptorTable();
+
+  // Checks that the currently open FDs did not change their metadata from
+  // stat(2), readlink(2) etc. Ignores FDs from |fds_to_ignore|.
+  //
+  // Temporary: allows newly open FDs if they pass the same checks as in
+  // Create(). This will be further restricted. See TODOs in the
+  // implementation.
   void Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn);
 
   // Reopens all file descriptors that are contained in the table. Returns true
@@ -91,8 +102,6 @@
 
   void RestatInternal(std::set<int>& open_fds, fail_fn_t fail_fn);
 
-  static int ParseFd(dirent* e, int dir_fd);
-
   // Invariant: All values in this unordered_map are non-NULL.
   std::unordered_map<int, FileDescriptorInfo*> open_fd_map_;
 
diff --git a/core/proto/android/server/apphibernationservice.proto b/core/proto/android/server/apphibernationservice.proto
index d341c4b..64c2a32 100644
--- a/core/proto/android/server/apphibernationservice.proto
+++ b/core/proto/android/server/apphibernationservice.proto
@@ -39,4 +39,5 @@
 message GlobalLevelHibernationStateProto {
   optional string package_name = 1;
   optional bool hibernated = 2;
+  optional int64 saved_byte = 3;
 }
\ No newline at end of file
diff --git a/core/res/res/layout/splash_screen_view.xml b/core/res/res/layout/splash_screen_view.xml
index e6d724f..0b7b49c 100644
--- a/core/res/res/layout/splash_screen_view.xml
+++ b/core/res/res/layout/splash_screen_view.xml
@@ -18,12 +18,15 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
+    android:padding="0dp"
     android:orientation="vertical">
 
     <View android:id="@+id/splashscreen_icon_view"
           android:layout_height="wrap_content"
           android:layout_width="wrap_content"
           android:layout_gravity="center"
+          android:padding="0dp"
+          android:background="@null"
           android:contentDescription="@string/splash_screen_view_icon_description"/>
 
     <View android:id="@+id/splashscreen_branding_view"
@@ -31,6 +34,8 @@
           android:layout_width="wrap_content"
           android:layout_gravity="center_horizontal|bottom"
           android:layout_marginBottom="60dp"
+          android:padding="0dp"
+          android:background="@null"
           android:contentDescription="@string/splash_screen_view_branding_description"/>
 
 </android.window.SplashScreenView>
\ No newline at end of file
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cd89318..a285cf7 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer \'n ander vingerafdruk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te helder"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probeer om dit te verstel"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander elke keer die posisie van jou vinger so effens"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk is gestaaf"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor benodig kalibrering"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index b261c46..71a07f3 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ሌላ የጣት አሻራ ይሞክሩ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"በጣም ብርሃናማ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ለማስተካከል ይሞክሩ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"የጣት አሻራ ትክክለኛነት ተረጋግጧል"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ዳሳሽ ማስተካከልን ይፈልጋል"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b38bf9f..661001b 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -597,6 +597,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"حاوِل تعديل بصمة الإصبع."</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"تم مصادقة بصمة الإصبع"</string>
@@ -613,8 +615,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"يحتاج المستشعر إلى المعايرة."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 846fb2c..15190e7 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য এটা ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰি চাওক"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অতি উজ্জ্বল"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"মিলাই চাওক"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ছেন্সৰৰ কেলিব্ৰেশ্বনৰ প্ৰয়োজন"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 6b4736f..25ae576 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başqa bir barmaq izini sınayın"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çox işıqlıdır"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Tənzimləməyə çalışın"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmaq izi doğrulandı"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor tənzimlənməlidir"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5fcd2df..ff17bab 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -588,6 +588,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string>
@@ -604,8 +605,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Senzor treba da se kalibriše"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 1af3ddd..a3eebb6 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Паспрабуйце іншы адбітак пальца"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Занадта светла"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Паспрабуйце наладзіць"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Адбітак пальца распазнаны"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Патрабуецца каліброўка датчыка"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b3722ab..38fdc499 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Опитайте с друг отпечатък"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Твърде светло е"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Опитайте да коригирате"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатъкът е удостоверен"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"За сензора се изисква калибриране"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 69ddbb4..16ab224 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য আঙ্গুলের ছাপ দিয়ে চেষ্টা করুন"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অত্যন্ত উজ্জ্বল"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"অ্যাডজাস্ট করার চেষ্টা করুন"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 74da24a..474e861 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -352,7 +352,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji proširivanje ili sužavanje statusne trake."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikaz obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Dozvoljava aplikaciji da prikazuje obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečica"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji dodavanje prečice za početni ekran bez intervencije korisnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uklanjanje prečica"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji uklanjanje prečice početnog ekrana bez intervencije korisnika."</string>
@@ -588,6 +588,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pokušajte s drugim otiskom prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte podesiti"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promijenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string>
@@ -604,8 +605,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Potrebno je kalibrirati senzor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 03e7ef2..3afb3cb 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova una altra empremta digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hi ha massa llum"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova d\'ajustar l\'empremta digital"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Cal calibrar el sensor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index bfd5634..07d1060 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -355,7 +355,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikaci rozbalit či sbalit stavový řádek."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Umožňuje aplikaci zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalace zástupců"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalace zástupců"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Umožňuje aplikaci přidat zástupce na plochu bez zásahu uživatele."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinstalace zástupců"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Umožňuje aplikaci odebrat zástupce z plochy bez zásahu uživatele."</string>
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zkuste provést úpravu"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisk byl ověřen"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Snímač vyžaduje kalibraci"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4231048..1099af6 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv at justere den"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensoren skal kalibreres"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 7a75eea..000d93a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Anderen Fingerabdruck verwenden"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zu hell"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Versuche, den Finger anders aufzulegen"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerabdruck wurde authentifiziert"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 523cde1..0dec36b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Δοκιμάστε άλλο δακτυλικό αποτύπωμα"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Υπερβολικά έντονος φωτισμός"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Δοκιμάστε να το προσαρμόσετε"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Ο αισθητήρας απαιτεί βαθμονόμηση"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b2eaab0..dc7528b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor needs calibration"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 0a257f4..db3d9f5 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor needs calibration"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 5eca8a68..c2ca314 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor needs calibration"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 74d32d4..994946f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor needs calibration"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 385608f..2fe89de 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎Try another fingerprint‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎Too bright‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎Try adjusting‎‏‎‎‏‎"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎Change the position of your finger slightly each time‎‏‎‎‏‎"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎Fingerprint authenticated‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index fafb766..e20574c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba ajustarla"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia un poco la posición del dedo cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Se debe calibrar el sensor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 3468da5..03d8529 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba a mover el dedo"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se ha autenticado la huella digital"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Hace falta calibrar el sensor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 0a60d66..efac8bc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -349,7 +349,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Võimaldab rakendusel laiendada või ahendada olekuriba."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Kuva märguanded lukustatud seadmes täisekraantegevustena"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lubab rakendusel märguandeid lukustatud seadmes täisekraantegevustena kuvada"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"otseteede installimine"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Otseteede installimine"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lubab rakendusel lisada avakuva otseteid ilma kasutaja sekkumiseta."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"otseteede desinstallimine"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Lubab rakendusel eemaldada avakuva otseteid ilma kasutaja sekkumiseta."</string>
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proovige teist sõrmejälge"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liiga ere"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proovige kohandada"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sõrmejälg autenditi"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Andurit on vaja kalibreerida"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e36cc32..708d7d6 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Erabili beste hatz-marka bat"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Argi gehiegi dago"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Saiatu doituta"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentifikatu da hatz-marka"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sentsorea kalibratu egin behar da"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
@@ -1055,8 +1056,8 @@
     <string name="last_month" msgid="1528906781083518683">"Azken hilabetea"</string>
     <string name="older" msgid="1645159827884647400">"Zaharragoa"</string>
     <string name="preposition_for_date" msgid="2780767868832729599">"<xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="preposition_for_time" msgid="4336835286453822053">"ordua: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="preposition_for_year" msgid="3149809685340130039">"urtea: <xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="4336835286453822053">"<xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="3149809685340130039">"<xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8394717255950176156">"egun"</string>
     <string name="days" msgid="4570879797423034973">"egun"</string>
     <string name="hour" msgid="7796325297097314653">"ordu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index add623a..0667fed 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"اثر انگشت دیگری را امتحان کنید"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"خیلی روشن است"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"اثر انگشت را تنظیم کنید"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالت‌سنجی شد"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"حسگر به واسنجی نیاز دارد"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
@@ -908,12 +909,12 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"لطفاً به راهنمای کاربر مراجعه کرده یا با مرکز پشتیبانی از مشتریان تماس بگیرید."</string>
     <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"سیم کارت قفل شد."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"بازگشایی قفل سیم کارت…"</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_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">"‏پین را<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> تلاش ناموفق دیگر داشته باشید،‌ از شما خواسته می‌شود با اطلاعات ورود به سیستم Google خود، قفل دستگاه Android TV را باز کنید.\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>
+    <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> تلاش ناموفق دیگر داشته باشید،‌ از شما خواسته می‌شود با اطلاعات ورود به سیستم Google خود، قفل دستگاه Android TV را باز کنید.\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>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل رایانهٔ لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"‏<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشته‌اید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، دستگاه Android TV شما به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد و همه داده‌های کاربر ازدست خواهد رفت."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از<xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
@@ -1671,16 +1672,16 @@
     <string name="kg_login_checking_password" msgid="4676010303243317253">"درحال بررسی حساب..."</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_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">"‏<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشته‌اید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، دستگاه Android TV شما به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد و همه داده‌های کاربر ازدست خواهد رفت."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. رایانه لوحی اکنون به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"‏<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشته‌اید. اکنون دستگاه Android TV شما به تنظیمات پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن اکنون به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"‏شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"‏<xliff:g id="NUMBER_0">%1$d</xliff:g> بار الگوی بازگشایی‌تان را اشتباه کشیده‌اید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته می‌شود بااستفاده از حساب ایمیل خود، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"‏شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"‏الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌‎اید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‎‌شود که بااستفاده از یک حساب ایمیل قفل رایانه لوحی‌تان را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"‏الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته می‌شود بااستفاده از حساب ایمیلتان، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"‏الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. پس‌از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌‎شود که بااستفاده از یک حساب ایمیل قفل تلفنتان را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"حذف"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش می‌دهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی می‌تواند به شنوایی‌تان آسیب وارد کند."</string>
@@ -1864,7 +1865,7 @@
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"کار دوم <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"کار سوم <xliff:g id="LABEL">%1$s</xliff:g>"</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_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبل‌از برداشتن سنجاق"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"توسط سرپرست سیستم نصب شد"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"توسط سرپرست سیستم به‌روزرسانی شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5b4caa7..2ae93b8 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Kokeile toista sormenjälkeä"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liian kirkas"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Kokeile muuttaa asentoa"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sormenjälki tunnistettu"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Tunnistin on kalibroitava"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 29c9698..143f3be 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte digitale"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop lumineux"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de l\'ajuster"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 23e599e..829c07c 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de repositionner le doigt"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Vous devez calibrer le capteur"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 70f703a..22a25c9 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proba con outra impresión dixital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hai demasiada luz"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proba a axustar a impresión dixital"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autenticouse a impresión dixital"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"É necesario calibrar o sensor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 4d27b10..702e169 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"અન્ય ફિંગરપ્રિન્ટ અજમાવી જુઓ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"અતિશય પ્રકાશિત"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ગોઠવણી કરી જુઓ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 74f4f46..8c668dc 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"किसी दूसरे फ़िंगरप्रिंट से कोशिश करें"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"बहुत रोशनी है"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेंसर पर सही तरीके से उंगली लगाने की कोशिश करें"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"सेंसर को कैलिब्रेट करने की ज़रूरत है"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 13a7c45..eb90708 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -588,6 +588,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Isprobajte drugi otisak prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte ga prilagoditi"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promijenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentificirano otiskom prsta"</string>
@@ -604,8 +605,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Potrebno je kalibrirati senzor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index a478e67..77db9e6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Próbálkozzon másik ujjlenyomattal"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Túl világos"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Próbálja beállítani"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Ujjlenyomat hitelesítve"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Az érzékelő kalibrálást igényel"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index e42eccb..0a18bfa 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Փորձեք մեկ այլ մատնահետք"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Շատ լուսավոր է"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Փորձեք փոխել մատի դիրքը"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ամեն անգամ թեթևակի փոխեք մատի դիրքը"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Մատնահետքը նույնականացվեց"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Սկաներն անհրաժեշտ է չափաբերել"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index f50c470..58cfdd7 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Coba sidik jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Coba sesuaikan"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sidik jari diautentikasi"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor memerlukan kalibrasi"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index bfc7476..210be91 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prófaðu annað fingrafar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Of bjart"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prófaðu að breyta stöðu fingursins"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Kvarða þarf skynjarann"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 708841d..7d08000 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova con un\'altra impronta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Troppa luce"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova a regolare"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia leggermente la posizione del dito ogni volta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impronta autenticata"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"È necessario calibrare il sensore"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fabffbf..8b3aece 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"יש להשתמש בטביעת אצבע אחרת"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"בהיר מדי"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"יש לנסות ולשנות את תנוחת האצבע"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"טביעת האצבע אומתה"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"צריך לכייל את החיישן"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e275df03..7b62919 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"別の指紋をお試しください"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"明るすぎます"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"調整してみてください"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"センサーの調整が必要です"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index bd85e61..8d9b99c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ცადეთ სხვა თითის ანაბეჭდი"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ზედმეტად ნათელია"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ცადეთ დარეგულირება"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"თითის ანაბეჭდი ავტორიზებულია"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"სენსორს კალიბრაცია სჭირდება"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 16da28f..80bddc7 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Дұрыстап қойып көріңіз."</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Саусақ ізі аутентификацияланды"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Датчикті калибрлеу қажет."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e72db13..aaa188b 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"សាកល្បងប្រើ​ស្នាមម្រាមដៃផ្សេងទៀត"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ភ្លឺពេក"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"សាកល្បង​កែតម្រូវ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"បាន​ផ្ទៀង​ផ្ទាត់​ស្នាម​ម្រាមដៃ"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិន​មាន​ការ​ចុះឈ្មោះស្នាម​ម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ឧបករណ៍​ចាប់សញ្ញាត្រូវការកែសម្រួល"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 8858d0b..fc7fa3b 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ಮತ್ತೊಂದು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ಸೆನ್ಸರ್‌ಗೆ ಕ್ಯಾಲಿಬ್ರೇಶನ್‌ನ ಅಗತ್ಯವಿದೆ"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index e9d0fc5..14b8514 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"조정 시도"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"지문이 인증됨"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"센서 보정 필요"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index c1961db..ccfdef8 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Башка манжа изин байкап көрүңүз"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Өтө жарык"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тууралап көрүңүз"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Сенсорду тууралоо керек"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 65643c3..e89dba7 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ລອງໃຊ້ລາຍນິ້ວມືອື່ນ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ແຈ້ງເກີນໄປ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ກະລຸນາລອງປັບແກ້"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ປ່ຽນຕຳແໜ່ງຂອງນິ້ວມືຂອງທ່ານເລັກນ້ອຍໃນແຕ່ລະເທື່ອ"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ພິສູດຢືນຢັນລາຍນິ້ວມືແລ້ວ"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ຕ້ອງປັບທຽບມາດຕະຖານເຊັນເຊີ"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9849124..ee9e61d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pabandykite kitą kontrolinį kodą"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Per šviesu"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pabandykite koreguoti"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Piršto antspaudas autentifikuotas"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Reikia sukalibruoti jutiklį"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8407622..1a90a81 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -588,6 +588,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Izmēģiniet citu pirksta nospiedumu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Pārāk spilgts"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Mēģiniet mainīt pozīciju"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pirksta nospiedums tika autentificēts."</string>
@@ -604,8 +606,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Nepieciešama sensora kalibrēšana."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 42a55c2..e028307 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте со друг отпечаток"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Премногу светло"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да го приспособите прстот"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатокот е проверен"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Сензорот треба да се калибрира"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f4a79e3..1b2e595 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"മറ്റൊരു ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് നോക്കുക"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"തെളിച്ചം വളരെയധികമാണ്"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"അൽപ്പം നീക്കി നോക്കൂ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിച്ചു"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"സെൻസറിന് കാലിബ്രേഷൻ ആവശ്യമാണ്"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 7d0a643..d21ce23 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Өөр хурууны хээ туршина уу"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Хэт гэрэлтэй байна"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тохируулж үзнэ үү"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Хурууны хээг нотолсон"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Мэдрэгчид тохируулга шаардлагатай"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 3933bf3..f1b21c0 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -349,7 +349,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"स्टेटस बार विस्तृत करण्यासाठी किंवा संक्षिप्त करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करणे"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करण्यासाठी ॲपला अनुमती द्या"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट स्‍थापित करा"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट इंस्टॉल करा"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट जोडण्‍याची अनुमती देते."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट विस्‍थापित करा"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट काढण्‍याची अनुमती देते."</string>
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"दुसरी फिंगरप्रिंट वापरून पाहा"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"खूप प्रखर"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"अ‍ॅडजस्ट करण्याचा प्रयत्न करा"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिंट ऑथेंटिकेट केली आहे"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 2ad6baf..bcc502a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Cuba cap jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Cuba selaraskan"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Cap jari disahkan"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Penderia memerlukan penentukuran"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 3543be0f..97db715 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"အခြားလက်ဗွေဖြင့် စမ်းကြည့်ပါ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"အာရုံခံကိရိယာက စံကိုက်ချိန်ညှိခြင်း လိုအပ်သည်"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9ed34e0..bb29d8e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv et annet fingeravtrykk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"For lyst"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv å justere"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrykket er godkjent"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensoren må kalibreres"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 25f59c2..c712fbd 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -349,7 +349,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"एपलाई स्थिति पट्टि विस्तार वा संकुचन गर्न अनुमति दिन्छ।"</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट स्थापना गर्नुहोस्"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट इन्स्टल गर्ने"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिन्छ।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"सर्टकटहरूको स्थापन रद्द गर्नुहोस्"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हटाउनको लागि अनुमति दिन्छ।"</string>
@@ -438,9 +438,9 @@
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"एपलाई अतिरिक्त स्थान प्रदायक आदेशहरू पहुँच गर्न अनुमति दिन्छ। यो एपलाई GPS वा अन्य स्थान स्रोतहरूको संचालन साथै हस्तक्षेप गर्न अनुमति दिन सक्छ।"</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"अग्रभूमिमा मात्र सटीक स्थानमाथि पहुँच राख्नुहोस्"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"यो एप चलाएका बेला यसले लोकेसनमा आधारित सेवाहरूबाट तपाईंको स्थानको सटीक जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसनमा आधारित सेवाहरू सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ। यसले ब्याट्रीको उपयोग बढाउन सक्छ।"</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"यो एप चलाएका बेला यसले लोकेसन सर्भिसबाट तपाईंको स्थानको सटीक जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसन सर्भिस सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ। यसले ब्याट्रीको उपयोग बढाउन सक्छ।"</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"अग्रभागमा मात्र अनुमानित स्थानमाथि पहुँच राख्नुहोस्"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"यो एप चलाएका बेला यसले लोकेसनमा आधारित सेवाहरूबाट तपाईंको स्थानको अनुमानित जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसनमा आधारित सेवाहरू सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ।"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"यो एप चलाएका बेला यसले लोकेसन सर्भिसबाट तपाईंको स्थानको अनुमानित जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसन सर्भिस सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ।"</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"पृष्ठभूमिमा स्थानसम्बन्धी पहुँच"</string>
     <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"यो एपले जुनसुकै बेला (एप नचलाएका बेलामा पनि) स्थानमाथि पहुँच राख्न सक्छ।"</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"तपाईँका अडियो सेटिङहरू परिवर्तन गर्नुहोस्"</string>
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"अर्को फिंगरप्रिन्ट प्रयोग गरी हेर्नुहोस्"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ज्यादै उज्यालो छ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेन्सरमा सही तरिकाले औँला राखेर हेर्नुहोस्"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिन्ट प्रमाणीकरण गरियो"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 307c125..cc75bd6 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer een andere vingerafdruk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te veel licht"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Verplaats je vinger"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander de positie van je vinger steeds een beetje"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor staat tijdelijk uit."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensor moet worden gekalibreerd"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 1e6eb37..f2fbbd0 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ଅନ୍ୟ ଏକ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ବହୁତ ଉଜ୍ଜ୍ୱଳ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ଆଡଜଷ୍ଟ କରି ଦେଖନ୍ତୁ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ଟିପଚିହ୍ନ ପ୍ରମାଣିତ ହେଲା"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index fbccb25..1804680 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ਕੋਈ ਹੋਰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤ ਕੇ ਦੇਖੋ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ਵਿਵਸਥਿਤ ਕਰਕੇ ਦੇਖੋ"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0671787..06c7779 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -591,6 +591,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Użyj odcisku innego palca"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zbyt jasno"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Popraw"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Uwierzytelniono odciskiem palca"</string>
@@ -607,8 +608,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Czujnik wymaga kalibracji"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 8c6b146..8729940 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"O sensor precisa ser calibrado"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 0fa0e50..543abc3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Experimente ajustar"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"A impressão digital foi autenticada."</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"O sensor necessita de calibração"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 8c6b146..8729940 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"O sensor precisa ser calibrado"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7bbf3e1..8e005e6 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -352,7 +352,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite aplicației să extindă sau să restrângă bara de stare."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite aplicației să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalează comenzi rapide"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalarea de comenzi rapide"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite unei aplicații să adauge comenzi rapide pe ecranul de pornire, fără intervenția utilizatorului."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"dezinstalează comenzi rapide"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite aplicației să elimine comenzi rapide de pe ecranul de pornire, fără intervenția utilizatorului."</string>
@@ -588,6 +588,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Încercați altă amprentă"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Prea luminos"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Încercați să ajustați"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Amprentă autentificată"</string>
@@ -604,8 +606,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Senzorul necesită calibrare"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ebe46e8..2d177cc 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Попробуйте сохранить отпечаток другого пальца."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Слишком светло."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Попробуйте изменить положение пальца."</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Требуется калибровка датчика."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index eea2594..e6d7956 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"තවත් ඇඟිලි සලකුණක් උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"දීප්තිය වැඩියි"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"සීරුමාරු කිරීම උත්සාහ කරන්න"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්‍යාපනය කරන ලදී"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"සංවේදකයට ක්‍රමාංකනය අවශ්‍යයි"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 234e3a8..18dcef3 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Vyskúšajte iný odtlačok prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Príliš jasno"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Vyskúšajte upraviť"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Odtlačok prsta bol overený"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Senzor vyžaduje kalibráciu"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 19c4434..0f13454 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -591,6 +591,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Poskusite z drugim prstnim odtisom."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvetlo je."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Poskusite popraviti položaj prsta."</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pristnost prstnega odtisa je preverjena"</string>
@@ -607,8 +609,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni registriranih prstnih odtisov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Tipalo je treba umeriti"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 7934473..2d45dd3 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Provo një gjurmë gishti tjetër"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Me shumë ndriçim"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Provo ta rregullosh"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Gjurma e gishtit u vërtetua"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensori ka nevojë për kalibrim"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a0ae389..6b96632 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -588,6 +588,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут лагано промените положај прста"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string>
@@ -604,8 +605,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Сензор треба да се калибрише"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 34d5e2c..58fcd9d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Testa ett annat fingeravtryck"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Det är för ljust"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Testa att justera fingeravtrycket"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensorn måste kalibreras"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cc8d644..8b34ba2 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Jaribu alama nyingine ya kidole"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Inang\'aa mno"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Jaribu kurekebisha"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Badilisha mkao wa kidole chako kiasi kila wakati"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Imethibitisha alama ya kidole"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Kitambuzi kinahitaji kurekebishwa"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 0d28151..adb8c47 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"வேறு கைரேகையை முயலவும்"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"அதிக வெளிச்சமாக உள்ளது"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"விரலைச் சரியாக வைக்கவும்"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"கைரேகை அங்கீகரிக்கப்பட்டது"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"சென்சாரைச் சீரமைக்க வேண்டும்"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 936b758..dac4c51 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"మరొక వేలిముద్రను ట్రై చేయండి"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"వెలుతురు అధికంగా ఉంది"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"సర్దుబాటు చేయడానికి ట్రై చేయండి"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"వేలిముద్ర ప్రమాణీకరించబడింది"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index 3ecb1dd..55e5685 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -42,4 +42,8 @@
 
     <!-- Allow SystemUI to show the shutdown dialog -->
     <bool name="config_showSysuiShutdown">true</bool>
+
+    <!-- Component name of the activity used to inform a user about a sensory being blocked because
+     of privacy settings. -->
+    <string name="config_sensorUseStartedActivity">com.android.systemui/com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9b2966f..b9ab264 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ลองลายนิ้วมืออื่น"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"สว่างเกินไป"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ลองปรับการวางนิ้ว"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ตรวจสอบสิทธิ์ลายนิ้วมือแล้ว"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"ต้องปรับเทียบเซ็นเซอร์"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index a34ac28..7678869 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Sumubok ng ibang fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Masyadong maliwanag"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Subukang isaayos"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Na-authenticate ang fingerprint"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Kailangang i-calibrate ang sensor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index a08dcb2..2f9a8b6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -585,6 +585,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başka bir parmak izi deneyin"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çok parlak"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ayarlamayı deneyin"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Her defasında parmağınızın konumunu biraz değiştirin"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Parmak izi kimlik doğrulaması yapıldı"</string>
@@ -601,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensörün kalibre edilmesi gerekiyor"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8be7da6..c04e3f0 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -591,6 +591,7 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Спробуйте інший відбиток пальця"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Надто яскраво"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Спробуйте відкоригувати відбиток пальця"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Щоразу трохи змінюйте положення пальця"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Відбиток пальця автентифіковано"</string>
@@ -607,8 +608,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Потрібно відкалібрувати датчик"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index e0344e0..07d683b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"دوسرا فنگر پرنٹ آزمائیں"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"کافی روشنی ہے"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ایڈجسٹ کرنے کی کوشش کریں"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"فنگر پرنٹ کی تصدیق ہو گئی"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"سینسر کو کیلیبریشن کی ضرورت ہے"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 25a6a1a..a64c1a8 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Boshqa barmoq izi bilan urining"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Juda yorqin"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Moslashga urining"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Sensorni sozlash kerak"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a5cfbaf..669adef 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Hãy thử một vân tay khác"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Quá sáng"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Hãy thử điều chỉnh"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Đã xác thực vân tay"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Cảm biến cần hiệu chỉnh"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 23832eb..ec8a7751e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"请试试其他指纹"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"光线太亮"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"请尝试调整指纹"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"已验证指纹"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"传感器需要校准"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 0b59e52..c91a426 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"嘗試調整"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"驗證咗指紋"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"需要校正感應器"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 8f81d83..89b48d6 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"請試著調整"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋驗證成功"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"必須校正感應器"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c5c7818..671f5f70 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -585,6 +585,8 @@
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zama ezinye izigxivizo zeminwe"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Kukhanya kakhulu"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zama ukulungisa"</string>
+    <!-- no translation found for fingerprint_acquired_immobile (1621891895241888048) -->
+    <skip />
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Izigxivizo zeminwe zigunyaziwe"</string>
@@ -601,8 +603,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"Inzwa idinga ukulinganisa"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f4aff94..67d29b5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1706,6 +1706,10 @@
          config_enableFusedLocationOverlay is false. -->
     <string name="config_fusedLocationProviderPackageName" translatable="false">com.android.location.fused</string>
 
+    <!-- Default value for the ADAS GNSS Location Enabled setting if this setting has never been
+         set before. -->
+    <bool name="config_defaultAdasGnssLocationEnabled" translatable="false">false</bool>
+
     <string-array name="config_locationExtraPackageNames" translatable="false"></string-array>
 
     <!-- The package name of the default network recommendation app.
@@ -1890,6 +1894,9 @@
          STREAM_MUSIC as if it's on TV platform. -->
     <bool name="config_single_volume">false</bool>
 
+    <!-- Flag indicating whether the volume panel should show remote sessions. -->
+    <bool name="config_volumeShowRemoteSessions">true</bool>
+
     <!-- Flag indicating that an outbound call must have a call capable phone account
          that has declared it can process the call's handle. -->
     <bool name="config_requireCallCapableAccountForHandle">false</bool>
@@ -4628,6 +4635,15 @@
     <!-- The package name for the default bug report handler app from power menu short press. This app must be allowlisted. -->
     <string name="config_defaultBugReportHandlerApp" translatable="false"></string>
 
+    <!-- When true, enables the allowlisted app to upload profcollect reports. -->
+    <bool name="config_profcollectReportUploaderEnabled">false</bool>
+
+    <!-- The package name for the default profcollect report uploader app. This app must be allowlisted. -->
+    <string name="config_defaultProfcollectReportUploaderApp" translatable="false"></string>
+
+    <!-- The action name for the default profcollect report uploader app. -->
+    <string name="config_defaultProfcollectReportUploaderAction" translatable="false"></string>
+
     <!-- The default value used for RawContacts.ACCOUNT_NAME when contacts are inserted without this
          column set. These contacts are stored locally on the device and will not be removed even
          if no android.account.Account with this name exists. A null string will be used if the
@@ -5007,6 +5023,10 @@
     <!-- Default value for Settings.ASSIST_TOUCH_GESTURE_ENABLED -->
     <bool name="config_assistTouchGestureEnabledDefault">true</bool>
 
+    <!-- The maximum byte size of the information contained in the bundle of
+    HotwordDetectedResult. -->
+    <integer translatable="false" name="config_hotwordDetectedResultMaxBundleSize">0</integer>
+
     <!-- The amount of dimming to apply to wallpapers with mid range luminance. 0 displays
          the wallpaper at full brightness. 1 displays the wallpaper as fully black. -->
     <item name="config_wallpaperDimAmount" format="float" type="dimen">0.05</item>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d4ddab1..bcd121a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1603,6 +1603,8 @@
     <string name="fingerprint_acquired_too_bright">Too bright</string>
     <!-- Message shown during fingerprint acquisition when a fingerprint must be adjusted.[CHAR LIMIT=50] -->
     <string name="fingerprint_acquired_try_adjusting">Try adjusting</string>
+    <!-- Message shown during fingerprint acquisition when a fingeprint area has already been captured during enrollment [CHAR LIMIT=100] -->
+    <string name="fingerprint_acquired_immobile">Change the position of your finger slightly each time</string>
     <!-- Array containing custom messages shown during fingerprint acquisision from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="fingerprint_acquired_vendor">
     </string-array>
@@ -1661,9 +1663,9 @@
     <!-- Notification name shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
     <string name="face_recalibrate_notification_name">Face Unlock</string>
     <!-- Notification title shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
-    <string name="face_recalibrate_notification_title">Re-enroll your face</string>
+    <string name="face_recalibrate_notification_title">Issue with Face Unlock</string>
     <!-- Notification content shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
-    <string name="face_recalibrate_notification_content">To improve recognition, please re-enroll your face</string>
+    <string name="face_recalibrate_notification_content">Tap to delete your face model, then add your face again</string>
     <!-- Title of a notification that directs the user to set up Face Unlock by enrolling their face. [CHAR LIMIT=NONE] -->
     <string name="face_setup_notification_title">Set up Face Unlock</string>
     <!-- Contents of a notification that directs the user to set up face unlock by enrolling their face. [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 46a834a..ea28215 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1918,6 +1918,7 @@
   <java-symbol type="bool" name="config_tintNotificationActionButtons" />
   <java-symbol type="bool" name="config_dozeAfterScreenOffByDefault" />
   <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
+  <java-symbol type="bool" name="config_defaultAdasGnssLocationEnabled" />
   <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
   <java-symbol type="bool" name="config_enableGeocoderOverlay" />
   <java-symbol type="bool" name="config_enableGeofenceOverlay" />
@@ -2539,6 +2540,7 @@
   <java-symbol type="string" name="fingerprint_error_hw_not_present" />
   <java-symbol type="string" name="fingerprint_error_security_update_required" />
   <java-symbol type="string" name="fingerprint_error_bad_calibration" />
+  <java-symbol type="string" name="fingerprint_acquired_immobile" />
 
   <!-- Fingerprint config -->
   <java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/>
@@ -4017,6 +4019,11 @@
   <java-symbol type="bool" name="config_bugReportHandlerEnabled" />
   <java-symbol type="string" name="config_defaultBugReportHandlerApp" />
 
+  <!-- For profcollect report uploader -->
+  <java-symbol type="bool" name="config_profcollectReportUploaderEnabled" />
+  <java-symbol type="string" name="config_defaultProfcollectReportUploaderApp" />
+  <java-symbol type="string" name="config_defaultProfcollectReportUploaderAction" />
+
   <java-symbol type="string" name="usb_device_resolve_prompt_warn" />
 
   <!-- For Accessibility system actions -->
@@ -4403,5 +4410,9 @@
   <java-symbol type="bool" name="config_assistLongPressHomeEnabledDefault" />
   <java-symbol type="bool" name="config_assistTouchGestureEnabledDefault" />
 
+  <java-symbol type="integer" name="config_hotwordDetectedResultMaxBundleSize" />
+
   <java-symbol type="dimen" name="config_wallpaperDimAmount" />
+
+  <java-symbol type="bool" name="config_volumeShowRemoteSessions" />
 </resources>
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java
deleted file mode 100644
index 6fad4b8d..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.appsearch.testing.AppSearchEmail;
-
-import com.google.common.collect.ImmutableSet;
-
-import org.junit.Test;
-
-import java.util.Set;
-
-public class PutDocumentsRequestTest {
-
-    @Test
-    public void addGenericDocument_byCollection() {
-        Set<AppSearchEmail> emails =
-                ImmutableSet.of(
-                        new AppSearchEmail.Builder("namespace", "test1").build(),
-                        new AppSearchEmail.Builder("namespace", "test2").build());
-        PutDocumentsRequest request =
-                new PutDocumentsRequest.Builder().addGenericDocuments(emails).build();
-
-        assertThat(request.getGenericDocuments().get(0).getId()).isEqualTo("test1");
-        assertThat(request.getGenericDocuments().get(1).getId()).isEqualTo("test2");
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java b/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java
new file mode 100644
index 0000000..057ecbd
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import org.junit.Test;
+
+public class IndentingStringBuilderTest {
+    @Test
+    public void testAppendIndentedStrings() {
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+        stringBuilder
+                .increaseIndentLevel()
+                .append("\nIndentLevel1\nIndentLevel1\n")
+                .decreaseIndentLevel()
+                .append("IndentLevel0,\n");
+
+        String str = stringBuilder.toString();
+        String expectedString = "\n  IndentLevel1\n  IndentLevel1\nIndentLevel0,\n";
+
+        assertThat(str).isEqualTo(expectedString);
+    }
+
+    @Test
+    public void testDecreaseIndentLevel_throwsException() {
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+
+        Exception e =
+                assertThrows(
+                        IllegalStateException.class, () -> stringBuilder.decreaseIndentLevel());
+        assertThat(e).hasMessageThat().contains("Cannot set indent level below 0.");
+    }
+
+    @Test
+    public void testAppendIndentedObjects() {
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+        Object stringProperty = "String";
+        Object longProperty = 1L;
+        Object booleanProperty = true;
+
+        stringBuilder
+                .append(stringProperty)
+                .append("\n")
+                .increaseIndentLevel()
+                .append(longProperty)
+                .append("\n")
+                .decreaseIndentLevel()
+                .append(booleanProperty);
+
+        String str = stringBuilder.toString();
+        String expectedString = "String\n  1\ntrue";
+
+        assertThat(str).isEqualTo(expectedString);
+    }
+
+    @Test
+    public void testAppendIndentedStrings_doesNotIndentLineBreak() {
+        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
+
+        stringBuilder
+                .append("\n")
+                .increaseIndentLevel()
+                .append("\n\n")
+                .decreaseIndentLevel()
+                .append("\n");
+
+        String str = stringBuilder.toString();
+        String expectedString = "\n\n\n\n";
+
+        assertThat(str).isEqualTo(expectedString);
+    }
+}
diff --git a/core/tests/coretests/src/android/os/VibratorTest.java b/core/tests/coretests/src/android/os/VibratorTest.java
index 8f9168b..0ece793 100644
--- a/core/tests/coretests/src/android/os/VibratorTest.java
+++ b/core/tests/coretests/src/android/os/VibratorTest.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertEquals;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -26,6 +28,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.hardware.vibrator.IVibrator;
 import android.media.AudioAttributes;
 import android.platform.test.annotations.Presubmit;
 
@@ -70,6 +73,54 @@
     }
 
     @Test
+    public void areEffectsSupported_noVibrator_returnsAlwaysNo() {
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[0]);
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void areEffectsSupported_unsupportedInOneVibrator_returnsNo() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo unsupportedVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setSupportedEffects(new int[0])
+                .build();
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void areEffectsSupported_unknownInOneVibrator_returnsUnknown() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo unknownSupportVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{supportedVibrator, unknownSupportVibrator});
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void arePrimitivesSupported_supportedInAllVibrators_returnsYes() {
+        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{firstVibrator, secondVibrator});
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
     public void arePrimitivesSupported_returnsArrayOfSameSize() {
         assertEquals(0, mVibratorSpy.arePrimitivesSupported(new int[0]).length);
         assertEquals(1, mVibratorSpy.arePrimitivesSupported(
@@ -80,6 +131,40 @@
     }
 
     @Test
+    public void arePrimitivesSupported_noVibrator_returnsAlwaysFalse() {
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[0]);
+        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void arePrimitivesSupported_unsupportedInOneVibrator_returnsFalse() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void arePrimitivesSupported_supportedInAllVibrators_returnsTrue() {
+        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 5)
+                .build();
+        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 15)
+                .build();
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{firstVibrator, secondVibrator});
+        assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
     public void getPrimitivesDurations_returnsArrayOfSameSize() {
         assertEquals(0, mVibratorSpy.getPrimitiveDurations(new int[0]).length);
         assertEquals(1, mVibratorSpy.getPrimitiveDurations(
@@ -90,6 +175,40 @@
     }
 
     @Test
+    public void getPrimitivesDurations_noVibrator_returnsAlwaysZero() {
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[0]);
+        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void getPrimitivesDurations_unsupportedInOneVibrator_returnsZero() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void getPrimitivesDurations_supportedInAllVibrators_returnsMaxDuration() {
+        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+                .build();
+        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
+                new VibratorInfo[]{firstVibrator, secondVibrator});
+        assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
     public void vibrate_withAudioAttributes_createsVibrationAttributesWithSameUsage() {
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
         AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 89d2b74..72a145f 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -151,7 +151,7 @@
      * Gets the {@link KeyStore} operation handle corresponding to the provided JCA crypto
      * primitive.
      *
-     * <p>The following primitives are supported: {@link Cipher} and {@link Mac}.
+     * <p>The following primitives are supported: {@link Cipher}, {@link Signature} and {@link Mac}.
      *
      * @return KeyStore operation handle or {@code 0} if the provided primitive's KeyStore operation
      *         is not in progress.
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 70f03d2..f28ee82 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -117,7 +117,9 @@
     <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
          a slight touch slop around the expanded view. -->
     <dimen name="bubble_expanded_view_slop">8dp</dimen>
-    <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
+    <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded.
+         If this value changes then R.dimen.bubble_expanded_view_min_height in CtsVerifier
+         should also be updated. -->
     <dimen name="bubble_expanded_default_height">180dp</dimen>
     <!-- On large screens the width of the expanded view is restricted to this size. -->
     <dimen name="bubble_expanded_view_tablet_width">412dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index b2ac61c..cb27ad9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -249,6 +249,7 @@
                                 !activeControl.getSurfacePosition().equals(lastSurfacePosition);
                         final boolean leashChanged =
                                 !haveSameLeash(mImeSourceControl, activeControl);
+                        final InsetsSourceControl lastImeControl = mImeSourceControl;
                         mImeSourceControl = activeControl;
                         if (mAnimation != null) {
                             if (positionChanged) {
@@ -262,6 +263,9 @@
                                 removeImeSurface();
                             }
                         }
+                        if (lastImeControl != null) {
+                            lastImeControl.release(SurfaceControl::release);
+                        }
                     }
                 }
             }
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 46db35a..670af96 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
@@ -288,6 +288,7 @@
         // create splash screen view finished.
         final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
         final FrameLayout rootLayout = new FrameLayout(context);
+        rootLayout.setPadding(0, 0, 0, 0);
         final Runnable setViewSynchronized = () -> {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addSplashScreenView");
             // waiting for setContentView before relayoutWindow
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index c770150..45a4f6c 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -331,6 +331,8 @@
             mSkiaLayer.reset();
         }
 
+        mProperties.mutateLayerProperties().mutableStretchEffect().clear();
+        mStretchMask.clear();
         // Clear out the previous snapshot and the image filter the previous
         // snapshot was created with whenever the layer changes.
         mSnapshotResult.snapshot = nullptr;
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index 43f805d..17cd3ce 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -186,6 +186,7 @@
 
 static const float ZERO = 0.f;
 static const float INTERPOLATION_STRENGTH_VALUE = 0.7f;
+static const char CONTENT_TEXTURE[] = "uContentTexture";
 
 sk_sp<SkShader> StretchEffect::getShader(float width, float height,
                                          const sk_sp<SkImage>& snapshotImage,
@@ -207,7 +208,7 @@
         mBuilder = std::make_unique<SkRuntimeShaderBuilder>(getStretchEffect());
     }
 
-    mBuilder->child("uContentTexture") =
+    mBuilder->child(CONTENT_TEXTURE) =
             snapshotImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
                                       SkSamplingOptions(SkFilterMode::kLinear), matrix);
     mBuilder->uniform("uInterpolationStrength").set(&INTERPOLATION_STRENGTH_VALUE, 1);
@@ -226,7 +227,9 @@
     mBuilder->uniform("viewportWidth").set(&width, 1);
     mBuilder->uniform("viewportHeight").set(&height, 1);
 
-    return mBuilder->makeShader(nullptr, false);
+    auto result = mBuilder->makeShader(nullptr, false);
+    mBuilder->child(CONTENT_TEXTURE) = nullptr;
+    return result;
 }
 
 sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() {
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
index 25777c2..3eab9f0 100644
--- a/libs/hwui/effects/StretchEffect.h
+++ b/libs/hwui/effects/StretchEffect.h
@@ -113,6 +113,10 @@
         return !isEmpty();
     }
 
+    void clear() {
+        mBuilder = nullptr;
+    }
+
 private:
     static sk_sp<SkRuntimeEffect> getStretchEffect();
     mutable SkVector mStretchDirection{0, 0};
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 4cd3616..ecdd4b6 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -214,6 +214,25 @@
      *
      * <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
      * carrier phase measurement plus an accumulated integer number of carrier half cycles.
+     *
+     * <p> For signals that have databits, the carrier phase tracking loops typically use a costas
+     * loop discriminator.  This type of tracking loop introduces a half-cycle ambiguity that is
+     * resolved by searching through the received data for known patterns of databits (e.g. GPS uses
+     * the TLM word) which then determines the polarity of the incoming data and resolves the
+     * half-cycle ambiguity.
+     *
+     * <p>Before the half-cycle ambiguity has been resolved it is possible that the ADR_STATE_VALID
+     * flag is set:
+     *
+     * <ul>
+     *   <li> In cases where ADR_STATE_HALF_CYCLE_REPORTED is not set, the
+     *   ADR_STATE_HALF_CYCLE_RESOLVED flag will not be available. Here, a half wave length will be
+     *   added to the returned accumulated delta range uncertainty to indicate the half cycle
+     *   ambiguity.
+     *   <li> In cases where ADR_STATE_HALF_CYCLE_REPORTED is set, half cycle ambiguity will be
+     *   indicated via both the ADR_STATE_HALF_CYCLE_RESOLVED flag and as well a half wave length
+     *   added to the returned accumulated delta range uncertainty.
+     * </ul>
      */
     public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
 
@@ -1039,9 +1058,6 @@
      * with integer ambiguity resolution, to determine highly precise relative location between
      * receivers.
      *
-     * <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
-     * reported as {@link #ADR_STATE_VALID}.
-     *
      * <p>The alignment of the phase measurement will not be adjusted by the receiver so the
      * in-phase and quadrature phase components will have a quarter cycle offset as they do when
      * transmitted from the satellites. If the measurement is from a combination of the in-phase
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index c9e4e0a..5d5c0fc 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -122,6 +122,9 @@
     boolean isLocationEnabledForUser(int userId);
     void setLocationEnabledForUser(boolean enabled, int userId);
 
+    boolean isAdasGnssLocationEnabledForUser(int userId);
+    void setAdasGnssLocationEnabledForUser(boolean enabled, int userId);
+
     void addTestProvider(String name, in ProviderProperties properties,
         in List<String> locationTags, String packageName, @nullable String attributionTag);
     void removeTestProvider(String provider, String packageName, @nullable String attributionTag);
diff --git a/location/java/android/location/LastLocationRequest.java b/location/java/android/location/LastLocationRequest.java
index 9ea8048..0970c1c 100644
--- a/location/java/android/location/LastLocationRequest.java
+++ b/location/java/android/location/LastLocationRequest.java
@@ -34,12 +34,15 @@
 public final class LastLocationRequest implements Parcelable {
 
     private final boolean mHiddenFromAppOps;
+    private final boolean mAdasGnssBypass;
     private final boolean mLocationSettingsIgnored;
 
     private LastLocationRequest(
             boolean hiddenFromAppOps,
+            boolean adasGnssBypass,
             boolean locationSettingsIgnored) {
         mHiddenFromAppOps = hiddenFromAppOps;
+        mAdasGnssBypass = adasGnssBypass;
         mLocationSettingsIgnored = locationSettingsIgnored;
     }
 
@@ -56,6 +59,21 @@
     }
 
     /**
+     * Returns true if this request may access GNSS even if location settings would normally deny
+     * this, in order to enable automotive safety features. This field is only respected on
+     * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced
+     * Driving Assistance Systems) application.
+     *
+     * @return true if all limiting factors will be ignored to satisfy GNSS request
+     * @hide
+     */
+    // TODO: make this system api
+    public boolean isAdasGnssBypass() {
+        return mAdasGnssBypass;
+    }
+
+
+    /**
      * Returns true if location settings, throttling, background location limits, and any other
      * possible limiting factors will be ignored in order to satisfy this last location request.
      *
@@ -65,12 +83,22 @@
         return mLocationSettingsIgnored;
     }
 
+    /**
+     * Returns true if any bypass flag is set on this request. For internal use only.
+     *
+     * @hide
+     */
+    public boolean isBypass() {
+        return mAdasGnssBypass || mLocationSettingsIgnored;
+    }
+
     public static final @NonNull Parcelable.Creator<LastLocationRequest> CREATOR =
             new Parcelable.Creator<LastLocationRequest>() {
                 @Override
                 public LastLocationRequest createFromParcel(Parcel in) {
                     return new LastLocationRequest(
                             /* hiddenFromAppOps= */ in.readBoolean(),
+                            /* adasGnssBypass= */ in.readBoolean(),
                             /* locationSettingsIgnored= */ in.readBoolean());
                 }
                 @Override
@@ -86,6 +114,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel parcel, int flags) {
         parcel.writeBoolean(mHiddenFromAppOps);
+        parcel.writeBoolean(mAdasGnssBypass);
         parcel.writeBoolean(mLocationSettingsIgnored);
     }
 
@@ -99,12 +128,13 @@
         }
         LastLocationRequest that = (LastLocationRequest) o;
         return mHiddenFromAppOps == that.mHiddenFromAppOps
+                && mAdasGnssBypass == that.mAdasGnssBypass
                 && mLocationSettingsIgnored == that.mLocationSettingsIgnored;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mHiddenFromAppOps, mLocationSettingsIgnored);
+        return Objects.hash(mHiddenFromAppOps, mAdasGnssBypass, mLocationSettingsIgnored);
     }
 
     @NonNull
@@ -115,8 +145,11 @@
         if (mHiddenFromAppOps) {
             s.append("hiddenFromAppOps, ");
         }
+        if (mAdasGnssBypass) {
+            s.append("adasGnssBypass, ");
+        }
         if (mLocationSettingsIgnored) {
-            s.append("locationSettingsIgnored, ");
+            s.append("settingsBypass, ");
         }
         if (s.length() > "LastLocationRequest[".length()) {
             s.setLength(s.length() - 2);
@@ -131,6 +164,7 @@
     public static final class Builder {
 
         private boolean mHiddenFromAppOps;
+        private boolean mAdasGnssBypass;
         private boolean mLocationSettingsIgnored;
 
         /**
@@ -138,6 +172,7 @@
          */
         public Builder() {
             mHiddenFromAppOps = false;
+            mAdasGnssBypass = false;
             mLocationSettingsIgnored = false;
         }
 
@@ -146,6 +181,7 @@
          */
         public Builder(@NonNull LastLocationRequest lastLocationRequest) {
             mHiddenFromAppOps = lastLocationRequest.mHiddenFromAppOps;
+            mAdasGnssBypass = lastLocationRequest.mAdasGnssBypass;
             mLocationSettingsIgnored = lastLocationRequest.mLocationSettingsIgnored;
         }
 
@@ -164,6 +200,25 @@
         }
 
         /**
+         * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance
+         * Systems) client, which requires access to GNSS even if location settings would normally
+         * deny this, in order to enable auto safety features. This field is only respected on
+         * automotive devices, and only if the client is recognized as a legitimate ADAS
+         * application. Defaults to false.
+         *
+         * <p>Permissions enforcement occurs when resulting location request is actually used, not
+         * when this method is invoked.
+         *
+         * @hide
+         */
+        // TODO: make this system api
+        @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+        public @NonNull LastLocationRequest.Builder setAdasGnssBypass(boolean adasGnssBypass) {
+            mAdasGnssBypass = adasGnssBypass;
+            return this;
+        }
+
+        /**
          * If set to true, indicates that location settings, throttling, background location limits,
          * and any other possible limiting factors should be ignored in order to satisfy this
          * last location request. This is only intended for use in user initiated emergency
@@ -186,6 +241,7 @@
         public @NonNull LastLocationRequest build() {
             return new LastLocationRequest(
                     mHiddenFromAppOps,
+                    mAdasGnssBypass,
                     mLocationSettingsIgnored);
         }
     }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index ae44c5e..526b84e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -315,6 +315,33 @@
     public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED";
 
     /**
+     * Broadcast intent action when the ADAS (Advanced Driving Assistance Systems) GNSS location
+     * enabled state changes. Includes a boolean intent extra, {@link #EXTRA_ADAS_GNSS_ENABLED},
+     * with the enabled state of ADAS GNSS location. This broadcast only has meaning on automotive
+     * devices.
+     *
+     * @see #EXTRA_ADAS_GNSS_ENABLED
+     * @see #isAdasGnssLocationEnabled()
+     *
+     * @hide
+     */
+    // TODO: @SystemApi
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ADAS_GNSS_ENABLED_CHANGED =
+            "android.location.action.ADAS_GNSS_ENABLED_CHANGED";
+
+    /**
+     * Intent extra included with {@link #ACTION_ADAS_GNSS_ENABLED_CHANGED} broadcasts, containing
+     * the boolean enabled state of ADAS GNSS location.
+     *
+     * @see #ACTION_ADAS_GNSS_ENABLED_CHANGED
+     *
+     * @hide
+     */
+    // TODO: @SystemApi
+    public static final String EXTRA_ADAS_GNSS_ENABLED = "android.location.extra.ADAS_GNSS_ENABLED";
+
+    /**
      * Broadcast intent action indicating that a high power location requests
      * has either started or stopped being active.  The current state of
      * active location requests should be read from AppOpsManager using
@@ -621,6 +648,42 @@
     }
 
     /**
+     * Returns the current enabled/disabled state of ADAS (Advanced Driving Assistance Systems)
+     * GNSS location access for the given user. This controls safety critical automotive access to
+     * GNSS location. This only has meaning on automotive devices.
+     *
+     * @return true if ADAS location is enabled and false if ADAS location is disabled.
+     *
+     * @hide
+     */
+    //TODO: @SystemApi
+    public boolean isAdasGnssLocationEnabled() {
+        try {
+            return mService.isAdasGnssLocationEnabledForUser(mContext.getUser().getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Enables or disables ADAS (Advanced Driving Assistance Systems) GNSS location access for the
+     * given user. This only has meaning on automotive devices.
+     *
+     * @param enabled true to enable ADAS location and false to disable ADAS location.
+     *
+     * @hide
+     */
+    // TODO: @SystemApi
+    @RequiresPermission(WRITE_SECURE_SETTINGS)
+    public void setAdasGnssLocationEnabled(boolean enabled) {
+        try {
+            mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the current enabled/disabled status of the given provider. To listen for changes, see
      * {@link #PROVIDERS_CHANGED_ACTION}.
      *
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index a3842a1..b48e596 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -194,6 +194,7 @@
     private float mMinUpdateDistanceMeters;
     private final long mMaxUpdateDelayMillis;
     private boolean mHideFromAppOps;
+    private final boolean mAdasGnssBypass;
     private boolean mLocationSettingsIgnored;
     private boolean mLowPower;
     private @Nullable WorkSource mWorkSource;
@@ -236,7 +237,7 @@
         if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
             quality = POWER_NONE;
         } else if (LocationManager.GPS_PROVIDER.equals(provider)) {
-            quality = ACCURACY_FINE;
+            quality = QUALITY_HIGH_ACCURACY;
         } else {
             quality = POWER_LOW;
         }
@@ -289,6 +290,7 @@
             float minUpdateDistanceMeters,
             long maxUpdateDelayMillis,
             boolean hiddenFromAppOps,
+            boolean adasGnssBypass,
             boolean locationSettingsIgnored,
             boolean lowPower,
             WorkSource workSource) {
@@ -302,8 +304,9 @@
         mMinUpdateDistanceMeters = minUpdateDistanceMeters;
         mMaxUpdateDelayMillis = maxUpdateDelayMillis;
         mHideFromAppOps = hiddenFromAppOps;
-        mLowPower = lowPower;
+        mAdasGnssBypass = adasGnssBypass;
         mLocationSettingsIgnored = locationSettingsIgnored;
+        mLowPower = lowPower;
         mWorkSource = Objects.requireNonNull(workSource);
     }
 
@@ -339,15 +342,15 @@
         switch (quality) {
             case POWER_HIGH:
                 // fall through
-            case ACCURACY_FINE:
+            case QUALITY_HIGH_ACCURACY:
                 mQuality = QUALITY_HIGH_ACCURACY;
                 break;
-            case ACCURACY_BLOCK:
+            case QUALITY_BALANCED_POWER_ACCURACY:
                 mQuality = QUALITY_BALANCED_POWER_ACCURACY;
                 break;
             case POWER_LOW:
                 // fall through
-            case ACCURACY_CITY:
+            case QUALITY_LOW_POWER:
                 mQuality = QUALITY_LOW_POWER;
                 break;
             case POWER_NONE:
@@ -648,6 +651,21 @@
     }
 
     /**
+     * Returns true if this request may access GNSS even if location settings would normally deny
+     * this, in order to enable automotive safety features. This field is only respected on
+     * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced
+     * Driving Assistance Systems) application.
+     *
+     * @return true if all limiting factors will be ignored to satisfy GNSS request
+     *
+     * @hide
+     */
+    // TODO: @SystemApi
+    public boolean isAdasGnssBypass() {
+        return mAdasGnssBypass;
+    }
+
+    /**
      * @hide
      * @deprecated LocationRequests should be treated as immutable.
      */
@@ -673,6 +691,15 @@
     }
 
     /**
+     * Returns true if any bypass flag is set on this request. For internal use only.
+     *
+     * @hide
+     */
+    public boolean isBypass() {
+        return mAdasGnssBypass || mLocationSettingsIgnored;
+    }
+
+    /**
      * @hide
      * @deprecated LocationRequests should be treated as immutable.
      */
@@ -749,6 +776,7 @@
                             /* minUpdateDistanceMeters= */ in.readFloat(),
                             /* maxUpdateDelayMillis= */ in.readLong(),
                             /* hiddenFromAppOps= */ in.readBoolean(),
+                            /* adasGnssBypass= */ in.readBoolean(),
                             /* locationSettingsIgnored= */ in.readBoolean(),
                             /* lowPower= */ in.readBoolean(),
                             /* workSource= */ in.readTypedObject(WorkSource.CREATOR));
@@ -777,6 +805,7 @@
         parcel.writeFloat(mMinUpdateDistanceMeters);
         parcel.writeLong(mMaxUpdateDelayMillis);
         parcel.writeBoolean(mHideFromAppOps);
+        parcel.writeBoolean(mAdasGnssBypass);
         parcel.writeBoolean(mLocationSettingsIgnored);
         parcel.writeBoolean(mLowPower);
         parcel.writeTypedObject(mWorkSource, 0);
@@ -801,6 +830,7 @@
                 && Float.compare(that.mMinUpdateDistanceMeters, mMinUpdateDistanceMeters) == 0
                 && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis
                 && mHideFromAppOps == that.mHideFromAppOps
+                && mAdasGnssBypass == that.mAdasGnssBypass
                 && mLocationSettingsIgnored == that.mLocationSettingsIgnored
                 && mLowPower == that.mLowPower
                 && Objects.equals(mProvider, that.mProvider)
@@ -866,8 +896,11 @@
         if (mHideFromAppOps) {
             s.append(", hiddenFromAppOps");
         }
+        if (mAdasGnssBypass) {
+            s.append(", adasGnssBypass");
+        }
         if (mLocationSettingsIgnored) {
-            s.append(", locationSettingsIgnored");
+            s.append(", settingsBypass");
         }
         if (mWorkSource != null && !mWorkSource.isEmpty()) {
             s.append(", ").append(mWorkSource);
@@ -889,6 +922,7 @@
         private float mMinUpdateDistanceMeters;
         private long mMaxUpdateDelayMillis;
         private boolean mHiddenFromAppOps;
+        private boolean mAdasGnssBypass;
         private boolean mLocationSettingsIgnored;
         private boolean mLowPower;
         @Nullable private WorkSource mWorkSource;
@@ -908,6 +942,7 @@
             mMinUpdateDistanceMeters = 0;
             mMaxUpdateDelayMillis = 0;
             mHiddenFromAppOps = false;
+            mAdasGnssBypass = false;
             mLocationSettingsIgnored = false;
             mLowPower = false;
             mWorkSource = null;
@@ -925,6 +960,7 @@
             mMinUpdateDistanceMeters = locationRequest.mMinUpdateDistanceMeters;
             mMaxUpdateDelayMillis = locationRequest.mMaxUpdateDelayMillis;
             mHiddenFromAppOps = locationRequest.mHideFromAppOps;
+            mAdasGnssBypass = locationRequest.mAdasGnssBypass;
             mLocationSettingsIgnored = locationRequest.mLocationSettingsIgnored;
             mLowPower = locationRequest.mLowPower;
             mWorkSource = locationRequest.mWorkSource;
@@ -977,10 +1013,10 @@
         public @NonNull Builder setQuality(@NonNull Criteria criteria) {
             switch (criteria.getAccuracy()) {
                 case Criteria.ACCURACY_COARSE:
-                    mQuality = ACCURACY_BLOCK;
+                    mQuality = QUALITY_BALANCED_POWER_ACCURACY;
                     break;
                 case Criteria.ACCURACY_FINE:
-                    mQuality = ACCURACY_FINE;
+                    mQuality = QUALITY_HIGH_ACCURACY;
                     break;
                 default: {
                     if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) {
@@ -1092,6 +1128,25 @@
         }
 
         /**
+         * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance
+         * Systems) client, which requires access to GNSS even if location settings would normally
+         * deny this, in order to enable auto safety features. This field is only respected on
+         * automotive devices, and only if the client is recognized as a legitimate ADAS
+         * application. Defaults to false.
+         *
+         * <p>Permissions enforcement occurs when resulting location request is actually used, not
+         * when this method is invoked.
+         *
+         * @hide
+         */
+        // TODO: @SystemApi
+        @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+        public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) {
+            mAdasGnssBypass = adasGnssBypass;
+            return this;
+        }
+
+        /**
          * If set to true, indicates that location settings, throttling, background location limits,
          * and any other possible limiting factors should be ignored in order to satisfy this
          * request. This is only intended for use in user initiated emergency situations, and
@@ -1171,6 +1226,7 @@
                     mMinUpdateDistanceMeters,
                     mMaxUpdateDelayMillis,
                     mHiddenFromAppOps,
+                    mAdasGnssBypass,
                     mLocationSettingsIgnored,
                     mLowPower,
                     new WorkSource(mWorkSource));
diff --git a/location/java/android/location/provider/ProviderRequest.java b/location/java/android/location/provider/ProviderRequest.java
index b72d365..4f33a52 100644
--- a/location/java/android/location/provider/ProviderRequest.java
+++ b/location/java/android/location/provider/ProviderRequest.java
@@ -44,12 +44,19 @@
     public static final long INTERVAL_DISABLED = Long.MAX_VALUE;
 
     public static final @NonNull ProviderRequest EMPTY_REQUEST = new ProviderRequest(
-            INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, 0, false, false, new WorkSource());
+            INTERVAL_DISABLED,
+            QUALITY_BALANCED_POWER_ACCURACY,
+            0,
+            false,
+            false,
+            false,
+            new WorkSource());
 
     private final long mIntervalMillis;
     private final @Quality int mQuality;
     private final long mMaxUpdateDelayMillis;
     private final boolean mLowPower;
+    private final boolean mAdasGnssBypass;
     private final boolean mLocationSettingsIgnored;
     private final WorkSource mWorkSource;
 
@@ -72,12 +79,14 @@
             @Quality int quality,
             long maxUpdateDelayMillis,
             boolean lowPower,
+            boolean adasGnssBypass,
             boolean locationSettingsIgnored,
             @NonNull WorkSource workSource) {
         mIntervalMillis = intervalMillis;
         mQuality = quality;
         mMaxUpdateDelayMillis = maxUpdateDelayMillis;
         mLowPower = lowPower;
+        mAdasGnssBypass = adasGnssBypass;
         mLocationSettingsIgnored = locationSettingsIgnored;
         mWorkSource = Objects.requireNonNull(workSource);
     }
@@ -126,6 +135,18 @@
     }
 
     /**
+     * Returns true if this request may access GNSS even if location settings would normally deny
+     * this, in order to enable automotive safety features. This field is only respected on
+     * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced
+     * Driving Assistance Systems) application.
+     *
+     * @hide
+     */
+    public boolean isAdasGnssBypass() {
+        return mAdasGnssBypass;
+    }
+
+    /**
      * Whether the provider should ignore all location settings, user consents, power restrictions
      * or any other restricting factors and always satisfy this request to the best of their
      * ability. This should only be used in case of a user initiated emergency.
@@ -135,6 +156,15 @@
     }
 
     /**
+     * Returns true if any bypass flag is set on this request.
+     *
+     * @hide
+     */
+    public boolean isBypass() {
+        return mAdasGnssBypass || mLocationSettingsIgnored;
+    }
+
+    /**
      * The power blame for this provider request.
      */
     public @NonNull WorkSource getWorkSource() {
@@ -153,6 +183,7 @@
                         /* quality= */ in.readInt(),
                         /* maxUpdateDelayMillis= */ in.readLong(),
                         /* lowPower= */ in.readBoolean(),
+                        /* adasGnssBypass= */ in.readBoolean(),
                         /* locationSettingsIgnored= */ in.readBoolean(),
                         /* workSource= */ in.readTypedObject(WorkSource.CREATOR));
             }
@@ -176,6 +207,7 @@
             parcel.writeInt(mQuality);
             parcel.writeLong(mMaxUpdateDelayMillis);
             parcel.writeBoolean(mLowPower);
+            parcel.writeBoolean(mAdasGnssBypass);
             parcel.writeBoolean(mLocationSettingsIgnored);
             parcel.writeTypedObject(mWorkSource, flags);
         }
@@ -198,6 +230,7 @@
                     && mQuality == that.mQuality
                     && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis
                     && mLowPower == that.mLowPower
+                    && mAdasGnssBypass == that.mAdasGnssBypass
                     && mLocationSettingsIgnored == that.mLocationSettingsIgnored
                     && mWorkSource.equals(that.mWorkSource);
         }
@@ -229,8 +262,11 @@
             if (mLowPower) {
                 s.append(", lowPower");
             }
+            if (mAdasGnssBypass) {
+                s.append(", adasGnssBypass");
+            }
             if (mLocationSettingsIgnored) {
-                s.append(", locationSettingsIgnored");
+                s.append(", settingsBypass");
             }
             if (!mWorkSource.isEmpty()) {
                 s.append(", ").append(mWorkSource);
@@ -246,10 +282,12 @@
      * A Builder for {@link ProviderRequest}s.
      */
     public static final class Builder {
+
         private long mIntervalMillis = INTERVAL_DISABLED;
         private int mQuality = QUALITY_BALANCED_POWER_ACCURACY;
         private long mMaxUpdateDelayMillis = 0;
         private boolean mLowPower;
+        private boolean mAdasGnssBypass;
         private boolean mLocationSettingsIgnored;
         private WorkSource mWorkSource = new WorkSource();
 
@@ -299,6 +337,16 @@
         }
 
         /**
+         * Sets whether this ADAS request should bypass GNSS settings. False by default.
+         *
+         * @hide
+         */
+        public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) {
+            this.mAdasGnssBypass = adasGnssBypass;
+            return this;
+        }
+
+        /**
          * Sets whether location settings should be ignored. False by default.
          */
         public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) {
@@ -326,6 +374,7 @@
                         mQuality,
                         mMaxUpdateDelayMillis,
                         mLowPower,
+                        mAdasGnssBypass,
                         mLocationSettingsIgnored,
                         mWorkSource);
             }
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 860d88a..d8f48c2 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -101,6 +101,8 @@
     private int mBatteryLevel;
     private int mBatteryScale;
     private int mDeviceType;
+    private String mHostType;
+    private boolean mSkipThumbForHost = false;
 
     private MtpServer mServer;
     private MtpStorageManager mManager;
@@ -192,6 +194,7 @@
             MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
             MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
             MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE,
+            MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,
     };
 
     @VisibleForNative
@@ -408,6 +411,8 @@
             }
             context.deleteDatabase(devicePropertiesName);
         }
+        mHostType = "";
+        mSkipThumbForHost = false;
     }
 
     @VisibleForNative
@@ -672,12 +677,24 @@
 
     @VisibleForNative
     private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) {
+        int length;
+        String value;
+
         switch (property) {
             case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
             case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
                 // writable string properties kept in shared preferences
-                String value = mDeviceProperties.getString(Integer.toString(property), "");
-                int length = value.length();
+                value = mDeviceProperties.getString(Integer.toString(property), "");
+                length = value.length();
+                if (length > 255) {
+                    length = 255;
+                }
+                value.getChars(0, length, outStringValue, 0);
+                outStringValue[length] = 0;
+                return MtpConstants.RESPONSE_OK;
+            case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
+                value = mHostType;
+                length = value.length();
                 if (length > 255) {
                     length = 255;
                 }
@@ -717,6 +734,14 @@
                 e.putString(Integer.toString(property), stringValue);
                 return (e.commit() ? MtpConstants.RESPONSE_OK
                         : MtpConstants.RESPONSE_GENERAL_ERROR);
+            case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
+                mHostType = stringValue;
+                if (stringValue.startsWith("Android/")) {
+                    Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property)
+                            + "=" + stringValue);
+                    mSkipThumbForHost = true;
+                }
+                return MtpConstants.RESPONSE_OK;
         }
 
         return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
@@ -838,6 +863,10 @@
                     outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0;
                     outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0);
                     outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0);
+                    if (mSkipThumbForHost) {
+                        Log.d(TAG, "getThumbnailInfo: Skip runtime thumbnail.");
+                        return true;
+                    }
                     if (exif.getThumbnailRange() != null) {
                         if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) {
                             Log.d(TAG, "getThumbnailInfo: check thumb info:"
@@ -880,6 +909,10 @@
                 try {
                     ExifInterface exif = new ExifInterface(path);
 
+                    if (mSkipThumbForHost) {
+                        Log.d(TAG, "getThumbnailData: Skip runtime thumbnail.");
+                        return exif.getThumbnail();
+                    }
                     if (exif.getThumbnailRange() != null)
                         return exif.getThumbnail();
                 } catch (IOException e) {
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index e8b04ed..ec92591 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -170,6 +170,18 @@
     }
 
     /**
+     * Set device property SESSION_INITIATOR_VERSION_INFO
+     *
+     * @param propertyStr string value for device property SESSION_INITIATOR_VERSION_INFO
+     * @return -1 for error, 0 for success
+     *
+     * {@hide}
+     */
+    public int setDevicePropertyInitVersion(@NonNull String propertyStr) {
+        return native_set_device_property_init_version(propertyStr);
+    }
+
+    /**
      * Returns the list of IDs for all storage units on this device
      * Information about each storage unit can be accessed via {@link #getStorageInfo}.
      *
@@ -421,6 +433,7 @@
     private native boolean native_open(String deviceName, int fd);
     private native void native_close();
     private native MtpDeviceInfo native_get_device_info();
+    private native int native_set_device_property_init_version(String propertyStr);
     private native int[] native_get_storage_ids();
     private native MtpStorageInfo native_get_storage_info(int storageId);
     private native int[] native_get_object_handles(int storageId, int format, int objectHandle);
diff --git a/media/java/android/mtp/MtpDeviceInfo.java b/media/java/android/mtp/MtpDeviceInfo.java
index 0304ee3..8851451 100644
--- a/media/java/android/mtp/MtpDeviceInfo.java
+++ b/media/java/android/mtp/MtpDeviceInfo.java
@@ -31,6 +31,7 @@
     private String mSerialNumber;
     private int[] mOperationsSupported;
     private int[] mEventsSupported;
+    private int[] mDevicePropertySupported;
 
     // only instantiated via JNI
     private MtpDeviceInfo() {
@@ -144,6 +145,21 @@
     }
 
     /**
+     * Returns Device property code supported by the device.
+     *
+     * @return supported Device property code. Can be null if device does not provide the property.
+     *
+     * @see MtpConstants#DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER
+     * @see MtpConstants#DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME
+     * @see MtpConstants#DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO
+     *
+     * {@hide}
+     */
+    public final @NonNull int[] getDevicePropertySupported() {
+        return mDevicePropertySupported;
+    }
+
+    /**
      * Returns if the given operation is supported by the device or not.
      * @param code Operation code.
      * @return If the given operation is supported by the device or not.
@@ -162,6 +178,17 @@
     }
 
     /**
+     * Returns if the given Device property is supported by the device or not.
+     * @param code Device property code.
+     * @return If the given Device property is supported by the device or not.
+     *
+     * {@hide}
+     */
+    public boolean isDevicePropertySupported(int code) {
+        return isSupported(mDevicePropertySupported, code);
+    }
+
+    /**
      * Returns if the code set contains code.
      * @hide
      */
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index ffed474..a77bc9f 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -1131,6 +1131,7 @@
     {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
     {   MTP_DEVICE_PROPERTY_BATTERY_LEVEL,              MTP_TYPE_UINT8 },
     {   MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE,      MTP_TYPE_UINT32 },
+    {   MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,     MTP_TYPE_STR },
 };
 
 bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -1289,6 +1290,7 @@
         switch (property) {
             case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
             case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+            case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
                 writable = true;
                 // fall through
                 FALLTHROUGH_INTENDED;
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 3d2b00fe..ac89fecd 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -72,6 +72,7 @@
 static jfieldID field_deviceInfo_serialNumber;
 static jfieldID field_deviceInfo_operationsSupported;
 static jfieldID field_deviceInfo_eventsSupported;
+static jfieldID field_deviceInfo_devicePropertySupported;
 
 // MtpStorageInfo fields
 static jfieldID field_storageInfo_storageId;
@@ -129,6 +130,8 @@
             GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I");
         field_deviceInfo_eventsSupported =
             GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I");
+        field_deviceInfo_devicePropertySupported =
+            GetFieldIDOrDie(env, clazz_deviceInfo, "mDevicePropertySupported", "[I");
 
         clazz_storageInfo =
             (jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo"));
@@ -377,9 +380,65 @@
         }
     }
 
+    assert(deviceInfo->mDeviceProperties);
+    {
+        const size_t size = deviceInfo->mDeviceProperties->size();
+        ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
+        {
+            ScopedIntArrayRW elements(env, events.get());
+            if (elements.get() == NULL) {
+                ALOGE("Could not create devicePropertySupported element.");
+                return NULL;
+            }
+            for (size_t i = 0; i < size; ++i) {
+                elements[i] = static_cast<int>(deviceInfo->mDeviceProperties->at(i));
+            }
+            env->SetObjectField(info, field_deviceInfo_devicePropertySupported, events.get());
+        }
+    }
+
     return info;
 }
 
+static jint
+android_mtp_MtpDevice_set_device_property_init_version(JNIEnv *env, jobject thiz,
+                                                       jstring property_str) {
+    MtpDevice* const device = get_device_from_object(env, thiz);
+
+    if (!device) {
+        ALOGD("%s device is null\n", __func__);
+        env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice.");
+        return -1;
+    }
+
+    const char *propertyStr = env->GetStringUTFChars(property_str, NULL);
+    if (propertyStr == NULL) {
+        return -1;
+    }
+
+    MtpProperty* property = new MtpProperty(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,
+                                            MTP_TYPE_STR, true);
+    if (!property) {
+        env->ThrowNew(clazz_io_exception, "Failed to obtain property.");
+        return -1;
+    }
+
+    if (property->getDataType() != MTP_TYPE_STR) {
+        env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
+        return -1;
+    }
+
+    property->setCurrentValue(propertyStr);
+    if (!device->setDevicePropValueStr(property)) {
+        env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
+        return -1;
+    }
+
+    env->ReleaseStringUTFChars(property_str, propertyStr);
+
+    return 0;
+}
+
 static jintArray
 android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz)
 {
@@ -847,6 +906,8 @@
     {"native_close",            "()V",  (void *)android_mtp_MtpDevice_close},
     {"native_get_device_info",  "()Landroid/mtp/MtpDeviceInfo;",
                                         (void *)android_mtp_MtpDevice_get_device_info},
+    {"native_set_device_property_init_version",  "(Ljava/lang/String;)I",
+                        (void *)android_mtp_MtpDevice_set_device_property_init_version},
     {"native_get_storage_ids",  "()[I", (void *)android_mtp_MtpDevice_get_storage_ids},
     {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;",
                                         (void *)android_mtp_MtpDevice_get_storage_info},
diff --git a/packages/CompanionDeviceManager/OWNERS b/packages/CompanionDeviceManager/OWNERS
index da723b3..734d8b6 100644
--- a/packages/CompanionDeviceManager/OWNERS
+++ b/packages/CompanionDeviceManager/OWNERS
@@ -1 +1 @@
-eugenesusla@google.com
\ No newline at end of file
+include /core/java/android/companion/OWNERS
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-gu/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values-gu/strings.xml
new file mode 100644
index 0000000..1fe4c5c
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-gu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"છોડી દો"</string>
+</resources>
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-te/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values-te/strings.xml
new file mode 100644
index 0000000..22a6f59
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-te/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"విస్మరించు"</string>
+</resources>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml
index 7d9b4d7..6acd9ff 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml
@@ -33,7 +33,7 @@
         android:background="?android:attr/colorPrimary"
         android:theme="@style/Theme.CollapsingToolbar.Settings">
 
-        <com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout
+        <com.google.android.material.appbar.CollapsingToolbarLayout
             android:id="@+id/collapsing_toolbar"
             android:layout_width="match_parent"
             android:layout_height="@dimen/toolbar_one_line_height"
@@ -59,7 +59,7 @@
                 android:transitionName="shared_element_view"
                 app:layout_collapseMode="pin"/>
 
-        </com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout>
+        </com.google.android.material.appbar.CollapsingToolbarLayout>
     </com.google.android.material.appbar.AppBarLayout>
 
     <FrameLayout
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
index 2a72a1a..63d397c 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml
@@ -17,6 +17,7 @@
 <resources>
     <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textSize">20dp</item>
     </style>
 
     <style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java
deleted file mode 100644
index 0e7e595..0000000
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.collapsingtoolbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.android.material.appbar.CollapsingToolbarLayout;
-
-/**
- * A customized version of CollapsingToolbarLayout that can apply different font size based on the
- * line count of its title.
- */
-public class AdjustableToolbarLayout extends CollapsingToolbarLayout {
-
-    private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
-
-    public AdjustableToolbarLayout(@NonNull Context context) {
-        this(context, null);
-
-    }
-
-    public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        initCollapsingToolbar();
-    }
-
-    @SuppressWarnings("RestrictTo")
-    private void initCollapsingToolbar() {
-        this.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
-            @Override
-            public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                v.removeOnLayoutChangeListener(this);
-                final int count = getLineCount();
-                if (count > TOOLBAR_MAX_LINE_NUMBER) {
-                    final ViewGroup.LayoutParams lp = getLayoutParams();
-                    lp.height = getResources()
-                            .getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
-                    setScrimVisibleHeightTrigger(
-                            getResources().getDimensionPixelSize(
-                                    R.dimen.scrim_visible_height_trigger_three_lines));
-                    setLayoutParams(lp);
-                } else if (count == TOOLBAR_MAX_LINE_NUMBER) {
-                    final ViewGroup.LayoutParams lp = getLayoutParams();
-                    lp.height = getResources()
-                            .getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
-                    setScrimVisibleHeightTrigger(
-                            getResources().getDimensionPixelSize(
-                                    R.dimen.scrim_visible_height_trigger_two_lines));
-                    setLayoutParams(lp);
-                }
-            }
-        });
-    }
-}
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 4ae120a..dbcecf1 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -35,10 +35,18 @@
  * A base Activity that has a collapsing toolbar layout is used for the activities intending to
  * enable the collapsing toolbar function.
  */
-public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
+public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity implements
+        AppBarLayout.OnOffsetChangedListener {
 
+    private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
+    private static final int FULLY_EXPANDED_OFFSET = 0;
+    private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
+
+    @Nullable
     private CollapsingToolbarLayout mCollapsingToolbarLayout;
+    @Nullable
     private AppBarLayout mAppBarLayout;
+    private boolean mIsToolbarCollapsed;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -48,6 +56,12 @@
         super.setContentView(R.layout.collapsing_toolbar_base_layout);
         mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
         mAppBarLayout = findViewById(R.id.app_bar);
+        mAppBarLayout.addOnOffsetChangedListener(this);
+        if (savedInstanceState != null) {
+            mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
+        }
+
+        initCollapsingToolbar();
         disableCollapsingToolbarLayoutScrollingBehavior();
 
         final Toolbar toolbar = findViewById(R.id.action_bar);
@@ -107,14 +121,43 @@
         return true;
     }
 
+    @Override
+    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
+        if (offset == FULLY_EXPANDED_OFFSET) {
+            mIsToolbarCollapsed = false;
+        } else {
+            mIsToolbarCollapsed = true;
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+        if (isChangingConfigurations()) {
+            outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed);
+        }
+    }
+
     /**
      * Returns an instance of collapsing toolbar.
      */
+    @Nullable
     public CollapsingToolbarLayout getCollapsingToolbarLayout() {
         return mCollapsingToolbarLayout;
     }
 
+    /**
+     * Return an instance of app bar.
+     */
+    @Nullable
+    public AppBarLayout getAppBarLayout() {
+        return mAppBarLayout;
+    }
+
     private void disableCollapsingToolbarLayoutScrollingBehavior() {
+        if (mAppBarLayout == null) {
+            return;
+        }
         final CoordinatorLayout.LayoutParams params =
                 (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
         final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
@@ -127,4 +170,39 @@
                 });
         params.setBehavior(behavior);
     }
+
+    @SuppressWarnings("RestrictTo")
+    private void initCollapsingToolbar() {
+        if (mCollapsingToolbarLayout == null || mAppBarLayout == null) {
+            return;
+        }
+        mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                v.removeOnLayoutChangeListener(this);
+                if (mIsToolbarCollapsed) {
+                    return;
+                }
+                final int count = mCollapsingToolbarLayout.getLineCount();
+                if (count > TOOLBAR_MAX_LINE_NUMBER) {
+                    final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
+                    lp.height = getResources()
+                            .getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
+                    mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
+                            getResources().getDimensionPixelSize(
+                                    R.dimen.scrim_visible_height_trigger_three_lines));
+                    mCollapsingToolbarLayout.setLayoutParams(lp);
+                } else if (count == TOOLBAR_MAX_LINE_NUMBER) {
+                    final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
+                    lp.height = getResources()
+                            .getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
+                    mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
+                            getResources().getDimensionPixelSize(
+                                    R.dimen.scrim_visible_height_trigger_two_lines));
+                    mCollapsingToolbarLayout.setLayoutParams(lp);
+                }
+            }
+        });
+    }
 }
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java
index c4c74ff..faa73ff 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java
@@ -25,21 +25,31 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
 import androidx.fragment.app.Fragment;
 
+import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
 
 /**
  * A base fragment that has a collapsing toolbar layout for enabling the collapsing toolbar design.
  */
-public abstract class CollapsingToolbarBaseFragment extends Fragment {
+public abstract class CollapsingToolbarBaseFragment extends Fragment implements
+        AppBarLayout.OnOffsetChangedListener {
+
+    private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
+    private static final int FULLY_EXPANDED_OFFSET = 0;
+    private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
 
     @Nullable
     private CollapsingToolbarLayout mCollapsingToolbarLayout;
+    @Nullable
+    private AppBarLayout mAppBarLayout;
     @NonNull
     private Toolbar mToolbar;
     @NonNull
     private FrameLayout mContentFrameLayout;
+    private boolean mIsToolbarCollapsed;
 
     @Nullable
     @Override
@@ -48,6 +58,13 @@
         final View view = inflater.inflate(R.layout.collapsing_toolbar_base_layout, container,
                 false);
         mCollapsingToolbarLayout = view.findViewById(R.id.collapsing_toolbar);
+        mAppBarLayout = view.findViewById(R.id.app_bar);
+        mAppBarLayout.addOnOffsetChangedListener(this);
+        if (savedInstanceState != null) {
+            mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
+        }
+        initCollapsingToolbar();
+        disableCollapsingToolbarLayoutScrollingBehavior();
         mToolbar = view.findViewById(R.id.action_bar);
         mContentFrameLayout = view.findViewById(R.id.content_frame);
         return view;
@@ -60,6 +77,31 @@
         requireActivity().setActionBar(mToolbar);
     }
 
+    @Override
+    public void onSaveInstanceState(@NonNull Bundle outState) {
+        super.onSaveInstanceState(outState);
+        if (getActivity().isChangingConfigurations()) {
+            outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed);
+        }
+    }
+
+    @Override
+    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
+        if (offset == FULLY_EXPANDED_OFFSET) {
+            mIsToolbarCollapsed = false;
+        } else {
+            mIsToolbarCollapsed = true;
+        }
+    }
+
+    /**
+     * Return an instance of app bar.
+     */
+    @Nullable
+    public AppBarLayout getAppBarLayout() {
+        return mAppBarLayout;
+    }
+
     /**
      * Return the collapsing toolbar layout.
      */
@@ -75,4 +117,56 @@
     public FrameLayout getContentFrameLayout() {
         return mContentFrameLayout;
     }
+
+    private void disableCollapsingToolbarLayoutScrollingBehavior() {
+        if (mAppBarLayout == null) {
+            return;
+        }
+        final CoordinatorLayout.LayoutParams params =
+                (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
+        final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
+        behavior.setDragCallback(
+                new AppBarLayout.Behavior.DragCallback() {
+                    @Override
+                    public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
+                        return false;
+                    }
+                });
+        params.setBehavior(behavior);
+    }
+
+    @SuppressWarnings("RestrictTo")
+    private void initCollapsingToolbar() {
+        if (mCollapsingToolbarLayout == null || mAppBarLayout == null) {
+            return;
+        }
+        mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                v.removeOnLayoutChangeListener(this);
+                if (mIsToolbarCollapsed) {
+                    return;
+                }
+                final int count = mCollapsingToolbarLayout.getLineCount();
+                if (count > TOOLBAR_MAX_LINE_NUMBER) {
+                    final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
+                    lp.height = getResources()
+                            .getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
+                    mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
+                            getResources().getDimensionPixelSize(
+                                    R.dimen.scrim_visible_height_trigger_three_lines));
+                    mCollapsingToolbarLayout.setLayoutParams(lp);
+                } else if (count == TOOLBAR_MAX_LINE_NUMBER) {
+                    final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
+                    lp.height = getResources()
+                            .getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
+                    mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
+                            getResources().getDimensionPixelSize(
+                                    R.dimen.scrim_visible_height_trigger_two_lines));
+                    mCollapsingToolbarLayout.setLayoutParams(lp);
+                }
+            }
+        });
+    }
 }
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml
index 9610c94..46f1e03 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml
@@ -25,6 +25,7 @@
 
     <style name="Switch.SettingsLib" parent="@android:style/Widget.Material.CompoundButton.Switch">
         <item name="android:switchMinWidth">52dp</item>
+        <item name="android:minHeight">@dimen/settingslib_preferred_minimum_touch_target</item>
         <item name="android:track">@drawable/settingslib_switch_track</item>
         <item name="android:thumb">@drawable/settingslib_switch_thumb</item>
     </style>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 89bb9e8..fa3f34c 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Stel gassessie terug"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gas"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bc1bd16..7b4c832 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"እንግዳን ዳግም አስጀምር"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"እንግዳ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index f04aaac..611f2c4 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"উপনাম"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"অতিথিৰ ছেশ্বন ৰিছেট কৰক"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b7cf11a..c50a22d 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Qonaq sessiyasını sıfırlayın"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Qonaq"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
@@ -576,7 +575,7 @@
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiv"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string>
-    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Simli qulaqlıq"</string>
+    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Naqilli qulaqlıq"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktiv"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Deaktiv"</string>
     <string name="carrier_network_change_mode" msgid="4257621815706644026">"Operator şəbəkəsinin dəyişilməsi"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 97c281a..e26d065 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 09e5843..7899fa6 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Нулиране на сесията като гост"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 88abe33..9eb20f9 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi sesiju gosta"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f499ab6..d3590bf 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Restableix el convidat"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Convidat"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 4d07eff..5c664b9 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Resetovat hosta"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Host"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 98f5301..59bfab8 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Επαναφορά περιόδου επισκέπτη"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Επισκέπτης"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 6ff4854..26c7b2c 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer invitado"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index ef7b7db..194aeaf 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Lähtesta külastajaseanss"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Külaline"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 9350610..33e2314 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -528,7 +528,7 @@
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
     <string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
     <string name="storage_category" msgid="2287342585424631813">"Biltegiratzea"</string>
-    <string name="shared_data_title" msgid="1017034836800864953">"Partekatutako datuak"</string>
+    <string name="shared_data_title" msgid="1017034836800864953">"Datu partekatuak"</string>
     <string name="shared_data_summary" msgid="5516326713822885652">"Ikusi eta aldatu partekatutako datuak"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Ez dago erabiltzaile honen datu partekaturik."</string>
     <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Errore bat gertatu da datu partekatuak eskuratzean. Saiatu berriro."</string>
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatua"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Berrezarri gonbidatuentzako saioa"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gonbidatua"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 964162b..a11a00a 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Nollaa vieras"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 73f98ec..dba912e 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer sesión de convidado"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 5620d94..bc74092 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान हटाएं"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट करें"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"मेहमान"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 0ff35f8..d18d34c 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi gostujuću sesiju"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 9bd4d12..3ad3590 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Vendég munkamenet visszaállítása"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Vendég"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 662a673..da92e7d 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Endurstilla gestastillingu"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gestur"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 2c2d11f..6f7565e 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Reimposta sessione Ospite"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Ospite"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index ddae3c7..70dd9e7 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Қонақ сеансын әдепкі күйге қайтару"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Қонақ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d970e95..26595f5 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"ឈ្មោះ​ហៅក្រៅ"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូល​ភ្ញៀវ"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"កំណត់​ភ្ញៀវឡើង​វិញ"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"ភ្ញៀវ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 8bad320..b36ef8d 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"ಅತಿಥಿಯನ್ನು ಮರುಹೊಂದಿಸಿ"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3383602..ad0ad1fb 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Iš naujo nustatyti svečią"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Svečias"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index d655afc..586de6fc 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Atiestatīt viesa sesiju"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Viesis"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index bd7f074..0d0f345 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Прекар"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Додајте гостин"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетирајте го гостинот"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Гостин"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 1e80ccd..655be1a7 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"അതിഥിയെ റീസെറ്റ് ചെയ്യുക"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 40b65ef..07ed369 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Хоч"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Зочныг шинэчлэх"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Зочин"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 6a46ede..fe8e837 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"अतिथी सेशन रीसेट करा"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 7156a8e..b383ad8 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည့် ထည့်ရန်"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်ရန်"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"ဧည့်သည်"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index bb93a29..84c231f 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Tilbakestill gjest"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gjest"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index a33bbf3..1837eab 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Gastsessie resetten"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gast"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 5f410a8..bd77d88 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesję gościa"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gość"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 3c8d928..e39b58b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index fc98aa7..a5c0d1d 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Alcunha"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Repor convidado"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 3c8d928..e39b58b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4db2f31..e1b0390 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adăugați un invitat"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Ștergeți invitatul"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Resetați sesiunea pentru invitați"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Invitat"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 0bcdc23..1e5fce5 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Сбросить гостевой сеанс"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Гость"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index ef12ad3..09c0bf9 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Obnoviť reláciu hosťa"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Hosť"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index cbdfefc..b698c19 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodajanje gosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Ponastavi gosta"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 3859be9..b3c23b6 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -567,8 +567,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 7dcca0d..124c063 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Återställ gästsession"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Gäst"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b7aff72..7f67b88 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -452,7 +452,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"อุปกรณ์อาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะเต็ม"</string>
+    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g>จึงจะเต็ม"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - อีก <xliff:g id="TIME">%2$s</xliff:g> จึงจะเต็ม"</string>
     <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - จำกัดการชาร์จชั่วคราว"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string>
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้ใช้ชั่วคราว"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้ใช้ชั่วคราวออก"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"รีเซ็ตผู้เข้าร่วม"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"ผู้ใช้ชั่วคราว"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6d1f6ab..cc7db29 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"I-reset ang bisita"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Bisita"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 82e481b..2cb1076 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -568,8 +568,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Скинути сеанс у режимі \"Гість\""</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Гість"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 7f4e30a..3e11124 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Nik"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Mehmon"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 2fe791a..0fa97e2 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -566,8 +566,7 @@
     <string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string>
-    <!-- no translation found for guest_reset_guest (6110013010356013758) -->
-    <skip />
+    <string name="guest_reset_guest" msgid="6110013010356013758">"Setha kabusha isivakashi"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Isihambeli"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 8c092ae..604310a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -454,6 +454,14 @@
                   android:finishOnCloseSystemDialogs="true">
         </activity>
 
+        <!-- started from SensoryPrivacyService -->
+        <activity android:name=".sensorprivacy.television.TvUnblockSensorActivity"
+                  android:exported="true"
+                  android:permission="android.permission.MANAGE_SENSOR_PRIVACY"
+                  android:theme="@style/BottomSheet"
+                  android:finishOnCloseSystemDialogs="true">
+        </activity>
+
 
         <!-- started from UsbDeviceSettingsManager -->
         <activity android:name=".usb.UsbAccessoryUriActivity"
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 149b313..0a036c8 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -85,7 +85,7 @@
     <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"‏تلاش‎های زیادی برای کشیدن الگو صورت گرفته است"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"پین خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"گذرواژه خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. \n\nلطفاً پس‌از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"کد پین سیم‌کارت اشتباه است، اکنون برای باز کردن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
       <item quantity="one">کد پین سیم‌کارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر می‌توانید تلاش کنید.</item>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index af43cf7..a41cce7 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string>
-    <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ હંગામી રૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string>
+    <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ હંગામીરૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string>
     <string name="keyguard_low_battery" msgid="1868012396800230904">"તમારું ચાર્જર કનેક્ટ કરો."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index b307544f..0692aef 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -36,7 +36,7 @@
     <string name="keyguard_charged" msgid="5478247181205188995">"चार्ज भयो"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तारविनै चार्ज गर्दै"</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गरिँदै"</string>
-    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै छ"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जिङ केही समयका लागि सीमित पारिएको छ"</string>
     <string name="keyguard_low_battery" msgid="1868012396800230904">"तपाईंको चार्जर जोड्नुहोस्।"</string>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
index 52fa2d8..cd98ef6 100644
--- a/packages/SystemUI/res-product/values-fa/strings.xml
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -38,8 +38,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشته‌اید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، نمایه کاری پاک می‌شود که با آن همه داده‌های نمایه حذف می‌شود."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشته‌اید. نمایه کاری پاک می‌شود که با آن همه داده‌های نمایه حذف می‌شود."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشته‌اید. نمایه کاری پاک می‌شود که با آن همه داده‌های نمایه حذف می‌شود."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"‏شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌شود که با استفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"‏الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌‎شود که بااستفاده از یک حساب ایمیل قفل رایانه لوحی‌تان را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. پس‌از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته می‌شود که بااستفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس‌از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"برای گزینه‌های بیشتر، قفل تلفن را باز کنید"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"برای گزینه‌های بیشتر، قفل رایانه لوحی را باز کنید"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"برای گزینه‌های بیشتر، قفل دستگاه را باز کنید"</string>
diff --git a/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml
new file mode 100644
index 0000000..fc3b4ed
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml
@@ -0,0 +1,52 @@
+<?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.
+  -->
+
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true">
+        <set>
+            <objectAnimator
+                android:duration="200"
+                android:propertyName="scaleX"
+                android:valueFrom="1.0"
+                android:valueTo="@dimen/bottom_sheet_button_selection_scaled"
+                android:valueType="floatType"/>
+            <objectAnimator
+                android:duration="200"
+                android:propertyName="scaleY"
+                android:valueFrom="1.0"
+                android:valueTo="@dimen/bottom_sheet_button_selection_scaled"
+                android:valueType="floatType"/>
+        </set>
+    </item>
+    <item android:state_focused="false">
+        <set>
+            <objectAnimator
+                android:duration="200"
+                android:propertyName="scaleX"
+                android:valueFrom="@dimen/bottom_sheet_button_selection_scaled"
+                android:valueTo="1.0"
+                android:valueType="floatType"/>
+            <objectAnimator
+                android:duration="200"
+                android:propertyName="scaleY"
+                android:valueFrom="@dimen/bottom_sheet_button_selection_scaled"
+                android:valueTo="1.0"
+                android:valueType="floatType"/>
+        </set>
+    </item>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml
index 93f8724..cace36d 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -15,11 +15,9 @@
   ~ limitations under the License.
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:interpolator="@android:interpolator/decelerate_quint">
+    <translate android:fromYDelta="100%"
+               android:toYDelta="0"
+               android:duration="900"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml
index 93f8724..f7efe7cd 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -15,11 +15,9 @@
   ~ limitations under the License.
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:interpolator="@android:interpolator/decelerate_quint">
+    <translate android:fromYDelta="0"
+               android:toYDelta="100%"
+               android:duration="500"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml b/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml
new file mode 100644
index 0000000..e6ceeb9
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml
@@ -0,0 +1,41 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together"
+     android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator"
+     android:duration="@integer/privacy_chip_animation_millis">
+    <objectAnimator
+        android:propertyName="height"
+        android:valueTo="@dimen/privacy_chip_dot_size"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="marginEnd"
+        android:valueTo="@dimen/privacy_chip_dot_margin_horizontal"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="radius"
+        android:valueTo="@dimen/privacy_chip_dot_radius"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="dotAlpha"
+        android:valueTo="255"
+        android:valueType="intType"/>
+    <objectAnimator
+        android:propertyName="bgAlpha"
+        android:valueTo="255"
+        android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml b/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml
new file mode 100644
index 0000000..4a510ae
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml
@@ -0,0 +1,41 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together"
+     android:interpolator="@interpolator/tv_privacy_chip_expand_interpolator"
+     android:duration="@integer/privacy_chip_animation_millis">
+    <objectAnimator
+        android:propertyName="height"
+        android:valueTo="@dimen/privacy_chip_height"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="marginEnd"
+        android:valueTo="0"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="radius"
+        android:valueTo="@dimen/privacy_chip_radius"
+        android:valueType="floatType"/>
+    <objectAnimator
+        android:propertyName="dotAlpha"
+        android:valueTo="255"
+        android:valueType="intType"/>
+    <objectAnimator
+        android:propertyName="bgAlpha"
+        android:valueTo="0"
+        android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml b/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml
new file mode 100644
index 0000000..701489a
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml
@@ -0,0 +1,25 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together"
+     android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator"
+     android:duration="@integer/privacy_chip_animation_millis">
+    <objectAnimator
+        android:propertyName="dotAlpha"
+        android:valueTo="255"
+        android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml b/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml
new file mode 100644
index 0000000..fa13471
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together"
+     android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator"
+     android:duration="@integer/privacy_chip_animation_millis">
+    <objectAnimator
+        android:propertyName="dotAlpha"
+        android:valueTo="0"
+        android:valueType="intType"/>
+    <objectAnimator
+        android:propertyName="bgAlpha"
+        android:valueTo="0"
+        android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/color/bottom_sheet_button_background_color.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/color/bottom_sheet_button_background_color.xml
index 93f8724..9b0bae0 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/color/bottom_sheet_button_background_color.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,8 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true"
+          android:color="@color/bottom_sheet_button_background_color_focused"/>
+    <item android:color="@color/bottom_sheet_button_background_color_unfocused"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/color/bottom_sheet_button_text_color.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/color/bottom_sheet_button_text_color.xml
index 93f8724..05248f1 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/color/bottom_sheet_button_text_color.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,8 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true"
+          android:color="@color/bottom_sheet_button_text_color_focused"/>
+    <item android:color="@color/bottom_sheet_button_text_color_unfocused"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/drawable/bottom_sheet_background.xml
similarity index 69%
rename from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
rename to packages/SystemUI/res/drawable/bottom_sheet_background.xml
index 93f8724..87850a0 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/drawable/bottom_sheet_background.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <solid android:color="@color/bottom_sheet_background_color"/>
+    <corners android:radius="@dimen/bottom_sheet_corner_radius"/>
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml
similarity index 69%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml
index 93f8724..cd2aa9c 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <solid android:color="@color/bottom_sheet_background_color_with_blur"/>
+    <corners android:radius="@dimen/bottom_sheet_corner_radius"/>
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/drawable/bottom_sheet_button_background.xml
similarity index 69%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/drawable/bottom_sheet_button_background.xml
index 93f8724..585a6bc 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/drawable/bottom_sheet_button_background.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <solid android:color="@color/bottom_sheet_button_background_color"/>
+    <corners android:radius="@dimen/bottom_sheet_button_corner_radius"/>
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.xml
index 93f8724..4298124 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -15,11 +15,8 @@
   ~ limitations under the License.
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="0.4"
+                  android:controlY1="1.00"
+                  android:controlX2="0.12"
+                  android:controlY2="1.00"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.xml
index 93f8724..ed44715 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -15,11 +15,8 @@
   ~ limitations under the License.
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="0.12"
+                  android:controlY1="1.00"
+                  android:controlX2="0.4"
+                  android:controlY2="1.00"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index b563633..16c03e1 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -81,6 +81,7 @@
                 android:visibility="gone"/>
             <SeekBar
                 android:id="@+id/volume_seekbar"
+                style="@*android:style/Widget.DeviceDefault.SeekBar"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_alignParentBottom="true"/>
diff --git a/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml
new file mode 100644
index 0000000..b53c88b
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+~ Copyright (C) 2021 The Android Open Source Project
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~      http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:id="@+id/item"
+    android:background="@drawable/people_tile_suppressed_background"
+    android:clipToOutline="true"
+    android:padding="8dp"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@+id/person_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:gravity="start"
+        android:id="@+id/text_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:singleLine="false"
+        android:text="@string/empty_status"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="@dimen/content_text_size_for_medium" />
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml
new file mode 100644
index 0000000..c79cdad
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+~ Copyright (C) 2021 The Android Open Source Project
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~      http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:id="@+id/item"
+    android:background="@drawable/people_tile_suppressed_background"
+    android:clipToOutline="true"
+    android:padding="8dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+
+    <ImageView
+        android:id="@+id/person_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:gravity="center"
+        android:id="@+id/text_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:singleLine="false"
+        android:text="@string/empty_status"
+        android:layout_marginTop="@dimen/padding_between_suppressed_layout_items"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+        android:textColor="?android:attr/textColorSecondary"
+        android:textSize="@dimen/content_text_size_for_large" />
+
+    <ImageView
+        android:id="@+id/predefined_icon"
+        android:tint="?android:attr/textColorSecondary"
+        android:layout_marginTop="@dimen/padding_between_suppressed_layout_items"
+        android:layout_width="@dimen/regular_predefined_icon"
+        android:layout_height="@dimen/regular_predefined_icon"
+        tools:ignore="UseAppTint" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/tv_bottom_sheet.xml b/packages/SystemUI/res/layout/tv_bottom_sheet.xml
new file mode 100644
index 0000000..b69cdc7
--- /dev/null
+++ b/packages/SystemUI/res/layout/tv_bottom_sheet.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/bottom_sheet"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:orientation="horizontal"
+    android:minHeight="@dimen/bottom_sheet_min_height"
+    android:paddingHorizontal="@dimen/bottom_sheet_padding_horizontal"
+    android:paddingVertical="@dimen/bottom_sheet_padding_vertical">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="80dp"
+        android:gravity="center"
+        android:orientation="horizontal">
+        <ImageView
+            android:id="@+id/bottom_sheet_icon"
+            android:layout_width="@dimen/bottom_sheet_icon_size"
+            android:layout_height="@dimen/bottom_sheet_icon_size"
+            android:layout_gravity="center_vertical"
+            android:tint="@color/bottom_sheet_icon_color"/>
+        <ImageView
+            android:id="@+id/bottom_sheet_second_icon"
+            android:layout_width="@dimen/bottom_sheet_icon_size"
+            android:layout_height="@dimen/bottom_sheet_icon_size"
+            android:layout_marginStart="@dimen/bottom_sheet_icon_margin"
+            android:layout_gravity="center_vertical"
+            android:tint="@color/bottom_sheet_icon_color"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/bottom_sheet_padding_horizontal"
+        android:layout_weight="1"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/bottom_sheet_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="@dimen/bottom_sheet_title_margin_bottom"
+            android:textAppearance="@style/BottomSheet.TitleText"/>
+
+        <TextView
+            android:id="@+id/bottom_sheet_body"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="@dimen/bottom_sheet_details_margin_bottom"
+            android:textAppearance="@style/BottomSheet.BodyText" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="@dimen/bottom_sheet_actions_width"
+        android:layout_height="match_parent"
+        android:gravity="center">
+        <Button
+            android:id="@+id/bottom_sheet_positive_button"
+            style="@style/BottomSheet.ActionItem" />
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="@dimen/bottom_sheet_actions_spacing" />
+        <Button
+            android:id="@+id/bottom_sheet_negative_button"
+            style="@style/BottomSheet.ActionItem" />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml
index dff148b..6218a5e 100644
--- a/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -20,16 +20,25 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:padding="12dp"
-    android:layout_gravity="center">
+    android:gravity="center"
+    android:animateLayoutChanges="false"
+    android:padding="@dimen/privacy_chip_margin">
+
+    <ImageView
+        android:id="@+id/chip_drawable"
+        android:layout_width="51dp"
+        android:layout_height="@dimen/privacy_chip_height"
+        android:minWidth="@dimen/privacy_chip_dot_bg_width"
+        android:minHeight="@dimen/privacy_chip_dot_bg_height"
+        android:layout_gravity="top|end" />
 
     <LinearLayout
         android:id="@+id/icons_container"
-        android:background="@drawable/tv_rect_shadow_rounded"
-        android:padding="@dimen/privacy_chip_icon_padding"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:orientation="horizontal"/>
-
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_gravity="center_vertical|end"
+        android:animateLayoutChanges="true"
+        android:paddingHorizontal="@dimen/privacy_chip_padding_horizontal" />
 </FrameLayout>
 
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml
index 93f8724..f22e8ef 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <fade android:fadingMode="fade_in" />
+    <changeBounds/>
+</transitionSet>
diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SystemUI/res/transition/tv_privacy_chip_expand.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
copy to packages/SystemUI/res/transition/tv_privacy_chip_expand.xml
index 93f8724..059ebc8 100644
--- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml
+++ b/packages/SystemUI/res/transition/tv_privacy_chip_expand.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2019 The Android Open Source Project
+  ~ Copyright (C) 2021 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ 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">
-
-    <corners android:radius="20dp"/>
-    <solid android:color="@color/tv_audio_recording_indicator_icon_background"/>
-    <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/>
-
-</shape>
\ No newline at end of file
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <changeBounds/>
+    <fade android:fadingMode="fade_out" />
+</transitionSet>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4736adb..ae8de87 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"ተጠቃሚ አክል"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"አዲስ ተጠቃሚ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"እንግዳ ይወገድ?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"እንግዳ ዳግም ይጀምር?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ዳግም አስጀምር"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"እንኳን በደህና ተመለሱ እንግዳ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index b493d89..2881a04 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -488,12 +488,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"إضافة مستخدم"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"مستخدم جديد"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"هل تريد إزالة جلسة الضيف؟"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"هل تريد إعادة ضبط جلسة الضيف؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"إعادة الضبط"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"مرحبًا بك مجددًا في جلسة الضيف"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index fe89267..345dcaa 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -482,12 +482,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li da uklonite gosta?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Želite li da resetujete sesiju gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetuj"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 0eedd1ca1..c035553 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"ব্যবহারকারী জুড়ুন"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যবহারকারী"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি সরাবেন?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"গেস্ট সেশন রিসেট করবেন?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"রিসেট করুন"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপনি ফিরে আসায় আপনাকে স্বাগত!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 615d346..ae7ac13 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -482,7 +482,7 @@
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
-    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti gostujuću sesiju?"</string>
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti sesiju gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
     <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Poništi"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 2428d55..14d3916 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Afegeix un usuari"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Usuari nou"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vols suprimir el convidat?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vols restablir el convidat?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Restableix"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvingut de nou, convidat."</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index d8e0a6a1..ae0f0f3 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Přidat uživatele"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nový uživatel"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstranit hosta?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Resetovat hosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetovat"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Vítejte zpět v relaci hosta!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ca44f0a..78a56cd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Tilføj bruger"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruger"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gæsten?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vil du nulstille gæsten?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Nulstil"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbage, gæst!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 17cb3b9..672ffd0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Nutzer hinzufügen"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Neuer Nutzer"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast entfernen?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Gastsitzung zurücksetzen?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Zurücksetzen"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Willkommen zurück im Gastmodus"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 7b135a3..3662da2 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Προσθήκη χρήστη"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Νέος χρήστης"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Κατάργηση επισκέπτη;"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Επαναφορά περιόδου επισκέπτη;"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Επαναφορά"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Kαλώς ορίσατε ξανά!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 0479ad0..13b7653 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Agregar usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Usuario nuevo"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"¿Quieres restablecer el usuario?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Restablecer"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"¡Hola de nuevo, invitado!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 6564815..171afee 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Añadir usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nuevo usuario"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"¿Restablecer invitado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Restablecer"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hola de nuevo, invitado"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 6d8a8fd..40f3998 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzaile bat"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gonbidatua kendu nahi duzu?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Gonbidatuentzako saioa berrezarri nahi duzu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Berrezarri"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ongi etorri berriro, gonbidatu hori!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ce3e676..f17fd41 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"افزودن کاربر"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"کاربر جدید"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مهمان حذف شود؟"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"جلسه مهمان بازنشانی شود؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"بازنشانی"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"مهمان گرامی، بازگشتتان را خوش آمد می‌گوییم!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا می‌خواهید جلسه‌تان را ادامه دهید؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 90f47ef..3546ea0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Lisää käyttäjä"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Uusi käyttäjä"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Poistetaaanko vieras?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Nollataanko vieras?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Nollaa"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tervetuloa takaisin!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 0304280..39d564f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Réinitialiser la session Invité?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Réinitialiser"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c402261..4f06701 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité ?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Réinitialiser la session Invité ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Réinitialiser"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e7b3e92..0641cef 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Engadir usuario"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuario"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres quitar o convidado?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Queres restablecer a sesión de convidado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Restablecer"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index a99558e..25caa53 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1036,8 +1036,7 @@
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"સ્વિચ"</string>
     <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ઍક્સેસિબિલિટી સંકેતને ઍક્સેસિબિલિટી બટન વડે બદલવામાં આવ્યા છે\n\n"<annotation id="link">"સેટિંગ જુઓ"</annotation></string>
-    <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
-    <skip />
+    <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"તમે ઍક્સેસિબિલિટી સંકેત પરથી કોઈ બટન પર સ્વિચ કરી શકો છો\n\n"<annotation id="link">"સેટિંગ"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"તેને હંગામી રૂપે ખસેડવા માટે બટનને કિનારી પર ખસેડો"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ઉપર ડાબે ખસેડો"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ઉપર જમણે ખસેડો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4196b1f..3d65fa4 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"उपयोगकर्ता जोड़ें"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नया उपयोगकर्ता"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"क्या आप मेहमान को हटाना चाहते हैं?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"क्या आप मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट करना चाहते हैं?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"रीसेट करें"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आप अपना सत्र जारी रखना चाहते हैं?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 01bad1c..151564a 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Bæta notanda við"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nýr notandi"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Fjarlægja gest?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Endurstilla gestastillingu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Endurstilla"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkominn aftur, gestur!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 32c386d..3dedff9 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"לאפס את הגלישה כאורח?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"איפוס"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 0b21c0f..7f57da1 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ಅತಿಥಿಯನ್ನು ಮರುಹೊಂದಿಸಬೇಕೆ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್‌ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ಮರುಹೊಂದಿಸಿ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 44dc8bb..ce64e4c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Pridėti naudotoją"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Naujas naudotojas"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Pašalinti svečią?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Nustatyti svečią iš naujo?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Nustatyti iš naujo"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Sveiki sugrįžę, svety!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b846be4..518a28b 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -482,12 +482,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Lietotāja pievienošana"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Jauns lietotājs"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vai noņemt viesi?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vai atiestatīt viesa sesiju?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Atiestatīt"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Laipni lūdzam atpakaļ, viesi!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 74d087c..6923fef 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"ഉപയോക്താവിനെ ചേര്‍ക്കുക"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"പുതിയ ഉപയോക്താവ്"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"അതിഥിയെ നീക്കംചെയ്യണോ?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"അതിഥിയെ റീസെറ്റ് ചെയ്യണോ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"റീസെറ്റ് ചെയ്യുക"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥി, വീണ്ടും സ്വാഗതം!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 84b5594..f649ca4 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"वापरकर्ता जोडा"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नवीन वापरकर्ता"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथी काढायचे?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"अतिथीला रीसेट करायचे आहे का?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"रीसेट करा"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथी, तुमचे पुन्‍हा स्‍वागत आहे!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index f3838c4..5034292 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Tambah pengguna"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baharu"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alih keluar tetamu?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Tetapkan semula tetamu?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Tetapkan semula"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat kembali, tetamu!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 71ae672..2f07a3e 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Legg til brukere"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruker"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gjesten?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vil du tilbakestille gjesten?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Tilbakestill"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 52e6155..10311b0 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -437,7 +437,7 @@
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"एपहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string>
     <string name="expanded_header_battery_charged" msgid="5307907517976548448">"चार्ज भयो"</string>
-    <string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै"</string>
+    <string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै छ"</string>
     <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण नभएसम्म"</string>
     <string name="expanded_header_battery_not_charging" msgid="809409140358955848">"चार्ज भइरहेको छैन"</string>
     <string name="ssl_ca_cert_warning" msgid="8373011375250324005">"नेटवर्क \n अनुगमनमा हुन सक्छ"</string>
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"अतिथि सत्र रिसेट गर्ने हो?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"रिसेट गर्नुहोस्"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"तपाईंलाई फेरि स्वागत छ, अतिथि"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 003ce4c..8fede32 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1036,8 +1036,7 @@
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚରକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନରେ ପରିବର୍ତ୍ତନ କରାଯାଇଛି\n\n"<annotation id="link">"ସେଟିଂସ୍ ଦେଖନ୍ତୁ"</annotation></string>
-    <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
-    <skip />
+    <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚରରୁ ଏକ ବଟନକୁ ସ୍ୱିଚ୍ କରିପାରିବେ\n\n"<annotation id="link">"ସେଟିଂସ୍"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ବଟନକୁ ଅସ୍ଥାୟୀ ଭାବେ ଲୁଚାଇବା ପାଇଁ ଏହାକୁ ଗୋଟିଏ ଧାରକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ଶୀର୍ଷ ବାମକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ଶୀର୍ଷ ଡାହାଣକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0f687a1..da10cb4 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ਕੀ ਮਹਿਮਾਨ ਹਟਾਉਣਾ ਹੈ?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ਕੀ ਗੈਸਟ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index e822d93..704d384 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Dodaj użytkownika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nowy użytkownik"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Usunąć gościa?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Zresetować sesję gościa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetuj"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, Gościu!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 3f9a576..42c8dbb 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -482,12 +482,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Adăugați un utilizator"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Utilizator nou"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ștergeți invitatul?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Resetați invitatul?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetați"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bine ați revenit în sesiunea pentru invitați!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 67091b9..e324c35 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Добавить пользователя"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Новый пользователь"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Удалить аккаунт гостя?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Сбросить гостевой сеанс?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Сбросить"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Рады видеть вас снова!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 19a871e..31bea13 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Pridať používateľa"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nový používateľ"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstrániť hosťa?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Chcete resetovať reláciu hosťa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetovať"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hosť, vitajte späť!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c58343a..420e8cb 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -484,12 +484,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Dodajanje uporabnika"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Nov uporabnik"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite odstraniti gosta?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Želite ponastaviti gosta?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Ponastavi"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Znova pozdravljeni, gost!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 334b2ed..e4238d2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Shto përdorues"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Përdorues i ri"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Të hiqet i ftuari?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Të rivendoset vizitori?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Rivendos"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e4a1bea..4e82fd7 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -482,12 +482,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Додај корисника"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Нови корисник"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Желите ли да уклоните госта?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Желите ли да ресетујете сесију госта?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Ресетуј"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 5dc1581..7e3b412 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"பயனரைச் சேர்"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"புதியவர்"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"கெஸ்ட்டை அகற்றவா?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"விருந்தினர் அமர்வை மீட்டமைக்கவா?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"மீட்டமை"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"நல்வரவு!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 348c37a..1f7146f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"యూజర్‌ను జోడించండి"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"కొత్త వినియోగదారు"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"గెస్ట్‌ను తీసివేయాలా?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"గెస్ట్ సెషన్‌ను రీసెట్ చేయాలా?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"రీసెట్ చేయండి"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్‌కు తిరిగి స్వాగతం!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
@@ -1038,8 +1036,7 @@
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మాగ్నిఫై చేయండి"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
     <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"యాక్సెసిబిలిటీ బటన్, యాక్సెసిబిలిటీ సంజ్ఞను భర్తీ చేసింది\n\n"<annotation id="link">"సెట్టింగ్‌లను చూడండి"</annotation></string>
-    <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
-    <skip />
+    <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"మీరు యాక్సెసిబిలిటీ సంజ్ఞ నుండి బటన్ మధ్య మారవచ్చు\n\n"<annotation id="link">"సెట్టింగ్‌లు"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్‌ను చివరకు తరలించండి"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ఎగువ ఎడమ వైపునకు తరలించు"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ఎగువ కుడి వైపునకు తరలించు"</string>
diff --git a/packages/SystemUI/res/values-television/colors.xml b/packages/SystemUI/res/values-television/colors.xml
index e5f3b47..566f6b2 100644
--- a/packages/SystemUI/res/values-television/colors.xml
+++ b/packages/SystemUI/res/values-television/colors.xml
@@ -19,4 +19,22 @@
 <resources>
     <color name="volume_dialog_background_color">#E61F232B</color>
     <color name="volume_dialog_background_color_above_blur">#C71F232B</color>
+
+    <color name="bottom_sheet_icon_color">#D2E3FC</color>
+
+    <color name="bottom_sheet_title_color">#E8F0FE</color>
+    <color name="bottom_sheet_body_color">#D2E3FC</color>
+
+    <color name="bottom_sheet_background_color">#1F232C</color>
+    <color name="bottom_sheet_background_color_with_blur">#AA1A2734</color>
+
+    <color name="bottom_sheet_button_background_color_focused">#E8F0FE</color>
+    <color name="bottom_sheet_button_background_color_unfocused">#0FE8EAED</color>
+
+    <color name="bottom_sheet_button_text_color_focused">#DB202124</color>
+    <color name="bottom_sheet_button_text_color_unfocused">#B5E8EAED</color>
+
+    <color name="privacy_circle">#5BB974</color> <!-- g400 -->
+    <color name="privacy_icon_tint">#30302A</color>
+    <color name="privacy_chip_dot_bg_tint">#66000000</color>
 </resources>
diff --git a/packages/SystemUI/res/values-television/dimens.xml b/packages/SystemUI/res/values-television/dimens.xml
index 7626db9..c258fcc 100644
--- a/packages/SystemUI/res/values-television/dimens.xml
+++ b/packages/SystemUI/res/values-television/dimens.xml
@@ -18,7 +18,42 @@
     <!-- Opacity at which the background for the shutdown UI will be drawn. -->
     <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">1.0</item>
 
-    <dimen name="privacy_chip_icon_margin">3dp</dimen>
-    <dimen name="privacy_chip_icon_padding">8dp</dimen>
-    <dimen name="privacy_chip_icon_size">13dp</dimen>
+    <dimen name="bottom_sheet_padding_horizontal">32dp</dimen>
+    <dimen name="bottom_sheet_padding_vertical">24dp</dimen>
+
+    <dimen name="bottom_sheet_icon_size">42dp</dimen>
+    <dimen name="bottom_sheet_icon_margin">8dp</dimen>
+    <dimen name="bottom_sheet_title_margin_bottom">18dp</dimen>
+    <dimen name="bottom_sheet_details_margin_bottom">8dp</dimen>
+
+    <dimen name="bottom_sheet_actions_width">296dp</dimen>
+    <dimen name="bottom_sheet_actions_spacing">12dp</dimen>
+    <item name="bottom_sheet_button_selection_scaled" format="float" type="dimen">1.1</item>
+    <dimen name="bottom_sheet_button_width">232dp</dimen>
+    <dimen name="bottom_sheet_button_padding_horizontal">20dp</dimen>
+    <dimen name="bottom_sheet_button_padding_vertical">16dp</dimen>
+
+    <dimen name="bottom_sheet_corner_radius">24dp</dimen>
+    <dimen name="bottom_sheet_button_corner_radius">10dp</dimen>
+
+    <dimen name="bottom_sheet_min_height">208dp</dimen>
+    <dimen name="bottom_sheet_margin">24dp</dimen>
+    <dimen name="bottom_sheet_background_blur_radius">120dp</dimen>
+
+    <dimen name="privacy_chip_margin">12dp</dimen>
+    <dimen name="privacy_chip_icon_margin_in_between">9dp</dimen>
+    <dimen name="privacy_chip_padding_horizontal">9dp</dimen>
+    <dimen name="privacy_chip_icon_size">12dp</dimen>
+    <dimen name="privacy_chip_height">24dp</dimen>
+    <dimen name="privacy_chip_min_width">30dp</dimen>
+    <dimen name="privacy_chip_radius">12dp</dimen>
+
+    <dimen name="privacy_chip_dot_size">8dp</dimen>
+    <dimen name="privacy_chip_dot_radius">4dp</dimen>
+    <dimen name="privacy_chip_dot_margin_horizontal">8dp</dimen>
+
+    <dimen name="privacy_chip_dot_bg_width">24dp</dimen>
+    <dimen name="privacy_chip_dot_bg_height">18dp</dimen>
+    <dimen name="privacy_chip_dot_bg_radius">9dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-television/integers.xml b/packages/SystemUI/res/values-television/integers.xml
index 587497e..b265d78 100644
--- a/packages/SystemUI/res/values-television/integers.xml
+++ b/packages/SystemUI/res/values-television/integers.xml
@@ -20,4 +20,6 @@
          Value 81 corresponds to BOTTOM|CENTER_HORIZONTAL.
          Value 21 corresponds to RIGHT|CENTER_VERTICAL. -->
     <integer name="volume_dialog_gravity">21</integer>
+
+    <integer name="privacy_chip_animation_millis">300</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-television/styles.xml b/packages/SystemUI/res/values-television/styles.xml
index 00217fb..0fb7898 100644
--- a/packages/SystemUI/res/values-television/styles.xml
+++ b/packages/SystemUI/res/values-television/styles.xml
@@ -28,4 +28,34 @@
         <item name="android:textColorPrimaryInverse">@color/tv_volume_dialog_accent</item>
         <item name="android:dialogCornerRadius">@dimen/volume_dialog_panel_width_half</item>
     </style>
+
+    <style name="BottomSheet" parent="Theme.Leanback">
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowActivityTransitions">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:backgroundDimAmount">0.2</item>
+    </style>
+
+    <style name="BottomSheet.TitleText">
+        <item name="android:textSize">28sp</item>
+        <item name="android:textColor">@color/bottom_sheet_title_color</item>
+    </style>
+
+    <style name="BottomSheet.BodyText">
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">@color/bottom_sheet_body_color</item>
+    </style>
+
+    <style name="BottomSheet.ActionItem">
+        <item name="android:layout_width">@dimen/bottom_sheet_button_width</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">left|center_vertical</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:textColor">@color/bottom_sheet_button_text_color</item>
+        <item name="android:background">@drawable/bottom_sheet_button_background</item>
+        <item name="android:paddingHorizontal">@dimen/bottom_sheet_button_padding_horizontal</item>
+        <item name="android:paddingVertical">@dimen/bottom_sheet_button_padding_vertical</item>
+        <item name="android:stateListAnimator">@anim/tv_bottom_sheet_button_state_list_animator</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 930bb05..efece98 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"صارف کو شامل کریں"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"نیا صارف"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مہمان کو ہٹائیں؟"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"مہمان کو ری سیٹ کریں؟"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ری سیٹ کریں"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"مہمان، پھر سے خوش آمدید!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 241cfb2..c337d08 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Thêm người dùng"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Người dùng mới"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Xóa phiên khách?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Đặt lại phiên khách?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Đặt lại"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Chào mừng bạn trở lại!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 7be08d3..b9ea4b0 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -480,7 +480,7 @@
     <string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
-    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重設訪客嗎?"</string>
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重設訪客工作階段嗎?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
     <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重設"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 5c4c3b15..7d82bf5 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"新增使用者"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重設訪客工作階段嗎?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重設"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 647102a..a44c6ff 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -480,12 +480,10 @@
     <string name="user_add_user" msgid="4336657383006913022">"Engeza umsebenzisi"</string>
     <string name="user_new_user_name" msgid="2019166282704195789">"Umsebenzisi omusha"</string>
     <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Susa isivakashi?"</string>
-    <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Setha kabusha isimenywa?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string>
-    <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
-    <skip />
+    <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Setha kabusha"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Siyakwamukela futhi, sivakashi!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7525a9b..4053ac3 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1451,7 +1451,7 @@
     <dimen name="people_space_messages_count_radius">12dp</dimen>
     <dimen name="people_space_widget_background_padding">6dp</dimen>
     <dimen name="required_width_for_medium">136dp</dimen>
-    <dimen name="required_width_for_large">138dp</dimen>
+    <dimen name="required_width_for_large">120dp</dimen>
     <dimen name="required_height_for_large">168dp</dimen>
     <dimen name="default_width">146dp</dimen>
     <dimen name="default_height">92dp</dimen>
@@ -1470,10 +1470,12 @@
     <dimen name="below_name_text_padding">16dp</dimen>
     <dimen name="above_notification_text_padding">22dp</dimen>
     <dimen name="regular_predefined_icon">18dp</dimen>
-    <dimen name="large_predefined_icon">24dp</dimen>
+    <dimen name="larger_predefined_icon">24dp</dimen>
+    <dimen name="largest_predefined_icon">32dp</dimen>
     <dimen name="availability_dot_status_padding">8dp</dimen>
     <dimen name="availability_dot_notification_padding">12dp</dimen>
     <dimen name="medium_content_padding_above_name">4dp</dimen>
+    <dimen name="padding_between_suppressed_layout_items">8dp</dimen>
 
     <!-- Accessibility floating menu -->
     <dimen name="accessibility_floating_menu_elevation">3dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 83dbad1..cf18b13 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2952,6 +2952,8 @@
     <string name="people_tile_description">See recent messages, missed calls, and status updates</string>
     <!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
     <string name="people_tile_title">Conversation</string>
+    <!-- Text when the Conversation widget when Do Not Disturb is suppressing the notification. [CHAR LIMIT=50] -->
+    <string name="paused_by_dnd">Paused by Do Not Disturb</string>
     <!-- Content description text on the Conversation widget when a person has sent a new text message [CHAR LIMIT=150] -->
     <string name="new_notification_text_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> sent a message</string>
     <!-- Content description text on the Conversation widget when a person has sent a new image message [CHAR LIMIT=150] -->
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
index 7cd43ef..cff6cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
@@ -19,6 +19,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
 
 import android.content.Context;
+import android.os.UserHandle;
 import android.text.TextUtils;
 
 import androidx.annotation.MainThread;
@@ -40,11 +41,11 @@
         AccessibilityButtonModeObserver.ModeChangedListener,
         AccessibilityButtonTargetsObserver.TargetsChangedListener {
 
-    private final Context mContext;
     private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
     private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
+    private Context mContext;
     @VisibleForTesting
     IAccessibilityFloatingMenu mFloatingMenu;
     private int mBtnMode;
@@ -79,6 +80,7 @@
 
         @Override
         public void onUserSwitchComplete(int userId) {
+            mContext = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */ 0);
             mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
             mBtnTargets =
                     mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index 5bb5522..e891e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.accessibility.floatingmenu;
 
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.util.MathUtils.constrain;
 import static android.util.MathUtils.sq;
 import static android.view.WindowInsets.Type.ime;
@@ -200,6 +201,7 @@
 
         mListView = listView;
         mWindowManager = context.getSystemService(WindowManager.class);
+        mLastConfiguration = new Configuration(getResources().getConfiguration());
         mAdapter = new AccessibilityTargetAdapter(mTargets);
         mUiHandler = createUiHandler();
         mPosition = position;
@@ -243,7 +245,6 @@
             }
         });
 
-        mLastConfiguration = new Configuration(getResources().getConfiguration());
 
         initListView();
         updateStrokeWith(getResources().getConfiguration().uiMode, mAlignment);
@@ -567,8 +568,10 @@
         final int currentX = (int) event.getX();
         final int currentY = (int) event.getY();
 
+        final int marginStartEnd = getMarginStartEndWith(mLastConfiguration);
         final Rect touchDelegateBounds =
-                new Rect(mMargin, mMargin, mMargin + getLayoutWidth(), mMargin + getLayoutHeight());
+                new Rect(marginStartEnd, mMargin, marginStartEnd + getLayoutWidth(),
+                        mMargin + getLayoutHeight());
         if (action == MotionEvent.ACTION_DOWN
                 && touchDelegateBounds.contains(currentX, currentY)) {
             mIsDownInEnlargedTouchArea = true;
@@ -682,15 +685,13 @@
         mListView.setLayoutManager(layoutManager);
         mListView.addOnItemTouchListener(this);
         mListView.animate().setInterpolator(new OvershootInterpolator());
-        updateListView();
+        updateListViewWith(mLastConfiguration);
 
         addView(mListView);
     }
 
-    private void updateListView() {
-        final LayoutParams layoutParams = (FrameLayout.LayoutParams) mListView.getLayoutParams();
-        layoutParams.setMargins(mMargin, mMargin, mMargin, mMargin);
-        mListView.setLayoutParams(layoutParams);
+    private void updateListViewWith(Configuration configuration) {
+        updateMarginWith(configuration);
 
         final int elevation =
                 getResources().getDimensionPixelSize(R.dimen.accessibility_floating_menu_elevation);
@@ -719,13 +720,15 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
+        mLastConfiguration.setTo(newConfig);
+
         final int diff = newConfig.diff(mLastConfiguration);
         if ((diff & ActivityInfo.CONFIG_LOCALE) != 0) {
             updateAccessibilityTitle(mCurrentLayoutParams);
         }
 
         updateDimensions();
-        updateListView();
+        updateListViewWith(newConfig);
         updateItemViewWith(mSizeType);
         updateColor();
         updateStrokeWith(newConfig.uiMode, mAlignment);
@@ -733,8 +736,6 @@
         updateRadiusWith(mSizeType, mRadiusType, mTargets.size());
         updateScrollModeWith(hasExceededMaxLayoutHeight());
         setSystemGestureExclusion();
-
-        mLastConfiguration.setTo(newConfig);
     }
 
     @VisibleForTesting
@@ -756,11 +757,11 @@
     }
 
     private int getMinWindowX() {
-        return -mMargin;
+        return -getMarginStartEndWith(mLastConfiguration);
     }
 
     private int getMaxWindowX() {
-        return mScreenWidth - mMargin - getLayoutWidth();
+        return mScreenWidth - getMarginStartEndWith(mLastConfiguration) - getLayoutWidth();
     }
 
     private int getMaxWindowY() {
@@ -805,6 +806,15 @@
         return layoutBottomY > imeY ? (layoutBottomY - imeY) : 0;
     }
 
+    private void updateMarginWith(Configuration configuration) {
+        // Avoid overlapping with system bars under landscape mode, update the margins of the menu
+        // to align the edge of system bars.
+        final int marginStartEnd = getMarginStartEndWith(configuration);
+        final LayoutParams layoutParams = (FrameLayout.LayoutParams) mListView.getLayoutParams();
+        layoutParams.setMargins(marginStartEnd, mMargin, marginStartEnd, mMargin);
+        mListView.setLayoutParams(layoutParams);
+    }
+
     private void updateOffsetWith(@ShapeType int shapeType, @Alignment int side) {
         final float halfWidth = getLayoutWidth() / 2.0f;
         final float offset = (shapeType == ShapeType.OVAL) ? 0 : halfWidth;
@@ -896,6 +906,12 @@
         return (mPadding + mIconHeight) * mTargets.size() + mPadding;
     }
 
+    private int getMarginStartEndWith(Configuration configuration) {
+        return configuration != null
+                && configuration.orientation == ORIENTATION_PORTRAIT
+                ? mMargin : 0;
+    }
+
     private @DimenRes int getRadiusResId(@SizeType int sizeType, int itemCount) {
         return sizeType == SizeType.SMALL
                 ? getSmallSizeResIdWith(itemCount)
@@ -932,7 +948,7 @@
     }
 
     private int getWindowWidth() {
-        return mMargin * 2 + getLayoutWidth();
+        return getMarginStartEndWith(mLastConfiguration) * 2 + getLayoutWidth();
     }
 
     private int getWindowHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index ec930b0..11412f4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -67,6 +67,7 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -111,6 +112,7 @@
     @NonNull private final FalsingManager mFalsingManager;
     @NonNull private final PowerManager mPowerManager;
     @NonNull private final AccessibilityManager mAccessibilityManager;
+    @NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     @Nullable private final UdfpsHbmProvider mHbmProvider;
     // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
     // sensors, this, in addition to a lot of the code here, will be updated.
@@ -507,6 +509,7 @@
             @NonNull FalsingManager falsingManager,
             @NonNull PowerManager powerManager,
             @NonNull AccessibilityManager accessibilityManager,
+            @NonNull LockscreenShadeTransitionController lockscreenShadeTransitionController,
             @NonNull ScreenLifecycle screenLifecycle,
             @Nullable Vibrator vibrator,
             @NonNull Optional<UdfpsHbmProvider> hbmProvider) {
@@ -529,6 +532,7 @@
         mFalsingManager = falsingManager;
         mPowerManager = powerManager;
         mAccessibilityManager = accessibilityManager;
+        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mHbmProvider = hbmProvider.orElse(null);
         screenLifecycle.addObserver(mScreenObserver);
         mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
@@ -716,6 +720,7 @@
                         mFgExecutor,
                         mDumpManager,
                         mKeyguardViewMediator,
+                        mLockscreenShadeTransitionController,
                         this
                 );
             case IUdfpsOverlayController.REASON_AUTH_BP:
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 00888df..35ca470 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -31,6 +31,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -54,6 +55,7 @@
     @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @NonNull private final DelayableExecutor mExecutor;
     @NonNull private final KeyguardViewMediator mKeyguardViewMediator;
+    @NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController;
     @NonNull private final UdfpsController mUdfpsController;
 
     @Nullable private Runnable mCancelDelayedHintRunnable;
@@ -63,6 +65,7 @@
     private boolean mFaceDetectRunning;
     private boolean mHintShown;
     private int mStatusBarState;
+    private float mTransitionToFullShadeProgress;
 
     /**
      * hidden amount of pin/pattern/password bouncer
@@ -81,12 +84,14 @@
             @NonNull DelayableExecutor mainDelayableExecutor,
             @NonNull DumpManager dumpManager,
             @NonNull KeyguardViewMediator keyguardViewMediator,
+            @NonNull LockscreenShadeTransitionController transitionController,
             @NonNull UdfpsController udfpsController) {
         super(view, statusBarStateController, statusBar, dumpManager);
         mKeyguardViewManager = statusBarKeyguardViewManager;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mExecutor = mainDelayableExecutor;
         mKeyguardViewMediator = keyguardViewMediator;
+        mLockScreenShadeTransitionController = transitionController;
         mUdfpsController = udfpsController;
     }
 
@@ -116,6 +121,7 @@
         updatePauseAuth();
 
         mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
+        mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(this);
     }
 
     @Override
@@ -127,6 +133,9 @@
         mStatusBarStateController.removeCallback(mStateListener);
         mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor);
         mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
+        if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
+            mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
+        }
 
         if (mCancelDelayedHintRunnable != null) {
             mCancelDelayedHintRunnable.run();
@@ -256,11 +265,21 @@
         }
     }
 
+    /**
+     * Set the progress we're currently transitioning to the full shade. 0.0f means we're not
+     * transitioning yet, while 1.0f means we've fully dragged down.
+     */
+    public void setTransitionToFullShadeProgress(float progress) {
+        mTransitionToFullShadeProgress = progress;
+        updateAlpha();
+    }
+
     private void updateAlpha() {
         // fade icon on transition to showing bouncer
         int alpha = mShowingUdfpsBouncer ? 255
                 : Math.abs((int) MathUtils.constrainedMap(0f, 255f, .4f, .7f,
                         mInputBouncerHiddenAmount));
+        alpha *= (1.0f - mTransitionToFullShadeProgress);
         mView.setUnpausedAlpha(alpha);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index 2dbf30f..de8ed70 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -25,6 +25,7 @@
 import com.android.systemui.screenrecord.ScreenRecordDialog;
 import com.android.systemui.screenshot.LongScreenshotActivity;
 import com.android.systemui.sensorprivacy.SensorUseStartedActivity;
+import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity;
 import com.android.systemui.settings.brightness.BrightnessDialog;
 import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
 import com.android.systemui.tuner.TunerActivity;
@@ -120,4 +121,10 @@
     @IntoMap
     @ClassKey(SensorUseStartedActivity.class)
     public abstract Activity bindSensorUseStartedActivity(SensorUseStartedActivity activity);
+
+    /** Inject into TvUnblockSensorActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(TvUnblockSensorActivity.class)
+    public abstract Activity bindTvUnblockSensorActivity(TvUnblockSensorActivity activity);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 746621d..d85c9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -231,7 +231,8 @@
             @Main Handler mainHandler,
             UiEventLogger uiEventLogger,
             NavigationBarOverlayController navBarOverlayController,
-            ConfigurationController configurationController) {
+            ConfigurationController configurationController,
+            UserTracker userTracker) {
         return new NavigationBarController(context,
                 windowManager,
                 assistManagerLazy,
@@ -256,7 +257,8 @@
                 mainHandler,
                 uiEventLogger,
                 navBarOverlayController,
-                configurationController);
+                configurationController,
+                userTracker);
     }
 
     /** */
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 053d75d..954ba79 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -63,6 +63,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.view.CrossWindowBlurListeners;
 import android.view.IWindowManager;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
@@ -139,6 +140,12 @@
     }
 
     @Provides
+    @Singleton
+    static CrossWindowBlurListeners provideCrossWindowBlurListeners() {
+        return CrossWindowBlurListeners.getInstance();
+    }
+
+    @Provides
     @DisplayId
     static int provideDisplayId(Context context) {
         return context.getDisplayId();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 0d5faff..1d6d1f2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -46,7 +46,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private ViewGroup mConnectedItem;
-    private boolean mInclueDynamicGroup;
+    private boolean mIncludeDynamicGroup;
 
     public MediaOutputAdapter(MediaOutputController controller) {
         super(controller);
@@ -56,7 +56,6 @@
     public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
             int viewType) {
         super.onCreateViewHolder(viewGroup, viewType);
-
         return new MediaDeviceViewHolder(mHolderView);
     }
 
@@ -66,7 +65,7 @@
         if (position == size && mController.isZeroMode()) {
             viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
                     true /* bottomMargin */);
-        } else if (mInclueDynamicGroup) {
+        } else if (mIncludeDynamicGroup) {
             if (position == 0) {
                 viewHolder.onBind(CUSTOMIZED_ITEM_DYNAMIC_GROUP, true /* topMargin */,
                         false /* bottomMargin */);
@@ -76,11 +75,12 @@
                 // from "position - 1".
                 viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices()))
                                 .get(position - 1),
-                        false /* topMargin */, position == size /* bottomMargin */);
+                        false /* topMargin */, position == size /* bottomMargin */, position);
             }
         } else if (position < size) {
             viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
-                    position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */);
+                    position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */,
+                    position);
         } else if (DEBUG) {
             Log.d(TAG, "Incorrect position: " + position);
         }
@@ -88,8 +88,8 @@
 
     @Override
     public int getItemCount() {
-        mInclueDynamicGroup = mController.getSelectedMediaDevice().size() > 1;
-        if (mController.isZeroMode() || mInclueDynamicGroup) {
+        mIncludeDynamicGroup = mController.getSelectedMediaDevice().size() > 1;
+        if (mController.isZeroMode() || mIncludeDynamicGroup) {
             // Add extra one for "pair new" or dynamic group
             return mController.getMediaDevices().size() + 1;
         }
@@ -120,15 +120,17 @@
         }
 
         @Override
-        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
-            super.onBind(device, topMargin, bottomMargin);
-            final boolean currentlyConnected = !mInclueDynamicGroup && isCurrentlyConnected(device);
+        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
+            super.onBind(device, topMargin, bottomMargin, position);
+            final boolean currentlyConnected = !mIncludeDynamicGroup
+                    && isCurrentlyConnected(device);
             if (currentlyConnected) {
                 mConnectedItem = mContainerLayout;
             }
             mBottomDivider.setVisibility(View.GONE);
             mCheckBox.setVisibility(View.GONE);
-            if (currentlyConnected && mController.isActiveRemoteDevice(device)) {
+            if (currentlyConnected && mController.isActiveRemoteDevice(device)
+                    && mController.getSelectableMediaDevice().size() > 0) {
                 // Init active device layout
                 mDivider.setVisibility(View.VISIBLE);
                 mDivider.setTransitionAlpha(1);
@@ -160,6 +162,7 @@
                     setTwoLineLayout(device, true /* bFocused */, true /* showSeekBar */,
                             false /* showProgressBar */, false /* showSubtitle */);
                     initSeekbar(device);
+                    mCurrentActivePosition = position;
                 } else {
                     setSingleLineLayout(getItemTitle(device), false /* bFocused */);
                     mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
@@ -186,11 +189,16 @@
                 mConnectedItem = mContainerLayout;
                 mBottomDivider.setVisibility(View.GONE);
                 mCheckBox.setVisibility(View.GONE);
-                mDivider.setVisibility(View.VISIBLE);
-                mDivider.setTransitionAlpha(1);
-                mAddIcon.setVisibility(View.VISIBLE);
-                mAddIcon.setTransitionAlpha(1);
-                mAddIcon.setOnClickListener(v -> onEndItemClick());
+                if (mController.getSelectableMediaDevice().size() > 0) {
+                    mDivider.setVisibility(View.VISIBLE);
+                    mDivider.setTransitionAlpha(1);
+                    mAddIcon.setVisibility(View.VISIBLE);
+                    mAddIcon.setTransitionAlpha(1);
+                    mAddIcon.setOnClickListener(v -> onEndItemClick());
+                } else {
+                    mDivider.setVisibility(View.GONE);
+                    mAddIcon.setVisibility(View.GONE);
+                }
                 mTitleIcon.setImageDrawable(getSpeakerDrawable());
                 final CharSequence sessionName = mController.getSessionName();
                 final CharSequence title = TextUtils.isEmpty(sessionName)
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index bcef43c..0890841 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -64,10 +64,12 @@
     Context mContext;
     View mHolderView;
     boolean mIsDragging;
+    int mCurrentActivePosition;
 
     public MediaOutputBaseAdapter(MediaOutputController controller) {
         mController = controller;
         mIsDragging = false;
+        mCurrentActivePosition = -1;
     }
 
     @Override
@@ -99,6 +101,10 @@
         return mIsAnimating;
     }
 
+    int getCurrentActivePosition() {
+        return mCurrentActivePosition;
+    }
+
     /**
      * ViewHolder for binding device view.
      */
@@ -136,7 +142,7 @@
             mCheckBox = view.requireViewById(R.id.check_box);
         }
 
-        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
+        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
             mDeviceId = device.getId();
             ThreadUtils.postOnBackgroundThread(() -> {
                 Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext);
@@ -214,6 +220,9 @@
         }
 
         void initSeekbar(MediaDevice device) {
+            if (!mController.isVolumeControlEnabled(device)) {
+                disableSeekBar();
+            }
             mSeekBar.setMax(device.getMaxVolume());
             mSeekBar.setMin(0);
             final int currentVolume = device.getCurrentVolume();
@@ -242,6 +251,7 @@
         }
 
         void initSessionSeekbar() {
+            disableSeekBar();
             mSeekBar.setMax(mController.getSessionVolumeMax());
             mSeekBar.setMin(0);
             final int currentVolume = mController.getSessionVolume();
@@ -330,5 +340,10 @@
                     PorterDuff.Mode.SRC_IN));
             return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
         }
+
+        private void disableSeekBar() {
+            mSeekBar.setEnabled(false);
+            mSeekBar.setOnTouchListener((v, event) -> true);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 8a9a6e6..cdcdf9a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -174,7 +174,12 @@
             mHeaderTitle.setGravity(Gravity.NO_GRAVITY);
         }
         if (!mAdapter.isDragging() && !mAdapter.isAnimating()) {
-            mAdapter.notifyDataSetChanged();
+            int currentActivePosition = mAdapter.getCurrentActivePosition();
+            if (currentActivePosition >= 0) {
+                mAdapter.notifyItemChanged(currentActivePosition);
+            } else {
+                mAdapter.notifyDataSetChanged();
+            }
         }
         // Show when remote media session is available
         mStopButton.setVisibility(getStopButtonVisibility());
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 8fee925..5293c88 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -465,6 +465,10 @@
                 || features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
     }
 
+    boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
+        return !device.getFeatures().contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK);
+    }
+
     private final MediaController.Callback mCb = new MediaController.Callback() {
         @Override
         public void onMetadataChanged(MediaMetadata metadata) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
index 24e076b..968c350 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
@@ -68,7 +68,7 @@
         final int size = mGroupMediaDevices.size();
         if (newPosition < size) {
             viewHolder.onBind(mGroupMediaDevices.get(newPosition), false /* topMargin */,
-                    newPosition == (size - 1) /* bottomMargin */);
+                    newPosition == (size - 1) /* bottomMargin */, position);
             return;
         }
         if (DEBUG) {
@@ -94,8 +94,8 @@
         }
 
         @Override
-        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
-            super.onBind(device, topMargin, bottomMargin);
+        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
+            super.onBind(device, topMargin, bottomMargin, position);
             mDivider.setVisibility(View.GONE);
             mAddIcon.setVisibility(View.GONE);
             mBottomDivider.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index da09793..711bb56 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -129,6 +129,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.AutoHideUiElement;
@@ -199,6 +200,7 @@
     private final Handler mHandler;
     private final NavigationBarOverlayController mNavbarOverlayController;
     private final UiEventLogger mUiEventLogger;
+    private final UserTracker mUserTracker;
 
     private Bundle mSavedState;
     private NavigationBarView mNavigationBarView;
@@ -232,7 +234,6 @@
 
     private boolean mTransientShown;
     private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
-    private int mA11yBtnMode;
     private LightBarController mLightBarController;
     private AutoHideController mAutoHideController;
 
@@ -459,7 +460,8 @@
             SystemActions systemActions,
             @Main Handler mainHandler,
             NavigationBarOverlayController navbarOverlayController,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            UserTracker userTracker) {
         mContext = context;
         mWindowManager = windowManager;
         mAccessibilityManager = accessibilityManager;
@@ -484,10 +486,10 @@
         mHandler = mainHandler;
         mNavbarOverlayController = navbarOverlayController;
         mUiEventLogger = uiEventLogger;
+        mUserTracker = userTracker;
 
         mNavBarMode = mNavigationModeController.addListener(this);
         mAccessibilityButtonModeObserver.addListener(this);
-        mA11yBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
     }
 
     public NavigationBarView getView() {
@@ -1375,8 +1377,9 @@
 
     private void setAccessibilityFloatingMenuModeIfNeeded() {
         if (QuickStepContract.isGesturalMode(mNavBarMode)) {
-            Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
-                    ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
+            Settings.Secure.putIntForUser(mContentResolver,
+                    Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
+                    ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU, UserHandle.USER_CURRENT);
         }
     }
 
@@ -1437,7 +1440,8 @@
 
         // If accessibility button is floating menu mode, click and long click state should be
         // disabled.
-        if (mA11yBtnMode == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
+        if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()
+                == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
             return 0;
         }
 
@@ -1450,12 +1454,14 @@
                 .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
         boolean longPressDefault = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault);
-        mLongPressHomeEnabled = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0) != 0;
+        mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver,
+                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0,
+                mUserTracker.getUserId()) != 0;
         boolean gestureDefault = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_assistTouchGestureEnabledDefault);
-        mAssistantTouchGestureEnabled = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0) != 0;
+        mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver,
+                Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0,
+                mUserTracker.getUserId()) != 0;
         if (mOverviewProxyService.getProxy() != null) {
             try {
                 mOverviewProxyService.getProxy().onAssistantAvailable(mAssistantAvailable
@@ -1546,7 +1552,6 @@
 
     @Override
     public void onAccessibilityButtonModeChanged(int mode) {
-        mA11yBtnMode = mode;
         updateAccessibilityServicesState(mAccessibilityManager);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index 8b5a537..5359210 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -57,6 +57,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -116,6 +117,7 @@
     private final TaskbarDelegate mTaskbarDelegate;
     private int mNavMode;
     private boolean mIsTablet;
+    private final UserTracker mUserTracker;
 
     /** A displayId - nav bar maps. */
     @VisibleForTesting
@@ -151,7 +153,8 @@
             @Main Handler mainHandler,
             UiEventLogger uiEventLogger,
             NavigationBarOverlayController navBarOverlayController,
-            ConfigurationController configurationController) {
+            ConfigurationController configurationController,
+            UserTracker userTracker) {
         mContext = context;
         mWindowManager = windowManager;
         mAssistManagerLazy = assistManagerLazy;
@@ -184,6 +187,7 @@
         mNavigationModeController.addListener(this);
         mTaskbarDelegate = new TaskbarDelegate(mOverviewProxyService);
         mIsTablet = isTablet(mContext.getResources().getConfiguration());
+        mUserTracker = userTracker;
     }
 
     @Override
@@ -361,7 +365,8 @@
                 mSystemActions,
                 mHandler,
                 mNavBarOverlayController,
-                mUiEventLogger);
+                mUiEventLogger,
+                mUserTracker);
         mNavigationBars.put(displayId, navBar);
 
         View navigationBarView = navBar.createView(savedState);
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
index 96aeb60..4ee951f 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
@@ -211,7 +211,8 @@
 
         @Override
         public void setColorFilter(ColorFilter colorFilter) {
-            // unimplemented
+            if (mAvatar != null) mAvatar.setColorFilter(colorFilter);
+            if (mBadgeIcon != null) mBadgeIcon.setColorFilter(colorFilter);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 0e17c8b..4a8775f 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -29,6 +29,8 @@
 import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
 import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
 import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.util.TypedValue.COMPLEX_UNIT_PX;
 
 import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT;
 import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT;
@@ -43,11 +45,16 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.graphics.text.LineBreaker;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.text.StaticLayout;
+import android.text.TextPaint;
 import android.text.TextUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
@@ -58,8 +65,11 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
+import androidx.annotation.DimenRes;
+import androidx.annotation.Px;
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
 import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+import androidx.core.math.MathUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.launcher3.icons.FastBitmapDrawable;
@@ -197,12 +207,16 @@
      */
     private RemoteViews getViewForTile() {
         if (DEBUG) Log.d(TAG, "Creating view for tile key: " + mKey.toString());
-        if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted()
-                || isDndBlockingTileData(mTile)) {
+        if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted()) {
             if (DEBUG) Log.d(TAG, "Create suppressed view: " + mTile);
             return createSuppressedView();
         }
 
+        if (isDndBlockingTileData(mTile)) {
+            if (DEBUG) Log.d(TAG, "Create dnd view");
+            return createDndRemoteViews().mRemoteViews;
+        }
+
         if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
             if (DEBUG) Log.d(TAG, "Create missed call view");
             return createMissedCallRemoteViews();
@@ -236,7 +250,9 @@
         return createLastInteractionRemoteViews();
     }
 
-    private boolean isDndBlockingTileData(PeopleSpaceTile tile) {
+    private static boolean isDndBlockingTileData(@Nullable PeopleSpaceTile tile) {
+        if (tile == null) return false;
+
         int notificationPolicyState = tile.getNotificationPolicyState();
         if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONVERSATIONS) != 0) {
             // Not in DND, or all conversations
@@ -413,6 +429,11 @@
             int avatarWidthSpace = mWidth - (14 + 14);
             avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace);
         }
+
+        if (isDndBlockingTileData(mTile)) {
+            avatarSize = createDndRemoteViews().mAvatarSize;
+        }
+
         return Math.min(avatarSize,
                 getSizeInDp(R.dimen.max_people_avatar_size));
     }
@@ -473,6 +494,87 @@
         return views;
     }
 
+    private RemoteViewsAndSizes createDndRemoteViews() {
+        boolean isHorizontal = mLayoutSize == LAYOUT_MEDIUM;
+        int layoutId = isHorizontal
+                ? R.layout.people_tile_with_suppression_detail_content_horizontal
+                : R.layout.people_tile_with_suppression_detail_content_vertical;
+        RemoteViews views = new RemoteViews(mContext.getPackageName(), layoutId);
+
+        int outerPadding = mLayoutSize == LAYOUT_LARGE ? 16 : 8;
+        int outerPaddingPx = dpToPx(outerPadding);
+        views.setViewPadding(
+                R.id.item,
+                outerPaddingPx,
+                outerPaddingPx,
+                outerPaddingPx,
+                outerPaddingPx);
+
+        int mediumAvatarSize = getSizeInDp(R.dimen.avatar_size_for_medium);
+        int maxAvatarSize = getSizeInDp(R.dimen.max_people_avatar_size);
+
+        String text = mContext.getString(R.string.paused_by_dnd);
+        views.setTextViewText(R.id.text_content, text);
+
+        int textSizeResId =
+                mLayoutSize == LAYOUT_LARGE
+                        ? R.dimen.content_text_size_for_large
+                        : R.dimen.content_text_size_for_medium;
+        float textSizePx = mContext.getResources().getDimension(textSizeResId);
+        views.setTextViewTextSize(R.id.text_content, COMPLEX_UNIT_PX, textSizePx);
+        int lineHeight = getLineHeightFromResource(textSizeResId);
+
+        int avatarSize;
+        if (isHorizontal) {
+            int maxTextHeight = mHeight - outerPadding;
+            views.setInt(R.id.text_content, "setMaxLines", maxTextHeight / lineHeight);
+            avatarSize = mediumAvatarSize;
+        } else {
+            int iconSize =
+                    getSizeInDp(
+                            mLayoutSize == LAYOUT_SMALL
+                                    ? R.dimen.regular_predefined_icon
+                                    : R.dimen.largest_predefined_icon);
+            int heightWithoutIcon = mHeight - 2 * outerPadding - iconSize;
+            int paddingBetweenElements =
+                    getSizeInDp(R.dimen.padding_between_suppressed_layout_items);
+            int maxTextWidth = mWidth - outerPadding * 2;
+            int maxTextHeight = heightWithoutIcon - mediumAvatarSize - paddingBetweenElements * 2;
+
+            int availableAvatarHeight;
+            int textHeight = estimateTextHeight(text, textSizeResId, maxTextWidth);
+            if (textHeight <= maxTextHeight) {
+                // If the text will fit, then display it and deduct its height from the space we
+                // have for the avatar.
+                availableAvatarHeight = heightWithoutIcon - textHeight - paddingBetweenElements * 2;
+                views.setViewVisibility(R.id.text_content, View.VISIBLE);
+                views.setInt(R.id.text_content, "setMaxLines", maxTextHeight / lineHeight);
+                views.setContentDescription(R.id.predefined_icon, null);
+            } else {
+                // If the height doesn't fit, then hide it. The dnd icon will still show.
+                availableAvatarHeight = heightWithoutIcon - paddingBetweenElements;
+                views.setViewVisibility(R.id.text_content, View.GONE);
+                // If we don't show the dnd text, set it as the content description on the icon
+                // for a11y.
+                views.setContentDescription(R.id.predefined_icon, text);
+            }
+
+            int availableAvatarWidth = mWidth - outerPadding * 2;
+            avatarSize =
+                    MathUtils.clamp(
+                            /* value= */ Math.min(availableAvatarWidth, availableAvatarHeight),
+                            /* min= */ dpToPx(10),
+                            /* max= */ maxAvatarSize);
+
+            views.setViewLayoutWidth(R.id.predefined_icon, iconSize, COMPLEX_UNIT_DIP);
+            views.setViewLayoutHeight(R.id.predefined_icon, iconSize, COMPLEX_UNIT_DIP);
+            views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_qs_dnd_on);
+        }
+
+        return new RemoteViewsAndSizes(views, avatarSize);
+    }
+
+
     private RemoteViews createMissedCallRemoteViews() {
         RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(),
                 getLayoutForContent()));
@@ -486,8 +588,8 @@
         views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed);
         if (mLayoutSize == LAYOUT_LARGE) {
             views.setInt(R.id.content, "setGravity", Gravity.BOTTOM);
-            views.setViewLayoutHeightDimen(R.id.predefined_icon, R.dimen.large_predefined_icon);
-            views.setViewLayoutWidthDimen(R.id.predefined_icon, R.dimen.large_predefined_icon);
+            views.setViewLayoutHeightDimen(R.id.predefined_icon, R.dimen.larger_predefined_icon);
+            views.setViewLayoutWidthDimen(R.id.predefined_icon, R.dimen.larger_predefined_icon);
         }
         setAvailabilityDotPadding(views, R.dimen.availability_dot_notification_padding);
         return views;
@@ -932,6 +1034,14 @@
         Drawable personDrawable = storyIcon.getPeopleTileDrawable(roundedDrawable,
                 tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
                 hasNewStory);
+
+        if (isDndBlockingTileData(tile)) {
+            // If DND is blocking the conversation, then display the icon in grayscale.
+            ColorMatrix colorMatrix = new ColorMatrix();
+            colorMatrix.setSaturation(0);
+            personDrawable.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
+        }
+
         return convertDrawableToBitmap(personDrawable);
     }
 
@@ -960,4 +1070,69 @@
             return context.getString(R.string.over_two_weeks_timestamp);
         }
     }
+
+    /**
+     * Estimates the height (in dp) which the text will have given the text size and the available
+     * width. Returns Integer.MAX_VALUE if the estimation couldn't be obtained, as this is intended
+     * to be used an estimate of the maximum.
+     */
+    private int estimateTextHeight(
+            CharSequence text,
+            @DimenRes int textSizeResId,
+            int availableWidthDp) {
+        StaticLayout staticLayout = buildStaticLayout(text, textSizeResId, availableWidthDp);
+        if (staticLayout == null) {
+            // Return max value (rather than e.g. -1) so the value can be used with <= bound checks.
+            return Integer.MAX_VALUE;
+        }
+        return pxToDp(staticLayout.getHeight());
+    }
+
+    /**
+     * Builds a StaticLayout for the text given the text size and available width. This can be used
+     * to obtain information about how TextView will lay out the text. Returns null if any error
+     * occurred creating a TextView.
+     */
+    @Nullable
+    private StaticLayout buildStaticLayout(
+            CharSequence text,
+            @DimenRes int textSizeResId,
+            int availableWidthDp) {
+        try {
+            TextView textView = new TextView(mContext);
+            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    mContext.getResources().getDimension(textSizeResId));
+            textView.setTextAppearance(android.R.style.TextAppearance_DeviceDefault);
+            TextPaint paint = textView.getPaint();
+            return StaticLayout.Builder.obtain(
+                    text, 0, text.length(), paint, dpToPx(availableWidthDp))
+                    // Simple break strategy avoids hyphenation unless there's a single word longer
+                    // than the line width. We use this break strategy so that we consider text to
+                    // "fit" only if it fits in a nice way (i.e. without hyphenation in the middle
+                    // of words).
+                    .setBreakStrategy(LineBreaker.BREAK_STRATEGY_SIMPLE)
+                    .build();
+        } catch (Exception e) {
+            Log.e(TAG, "Could not create static layout: " + e);
+            return null;
+        }
+    }
+
+    private int dpToPx(float dp) {
+        return (int) (dp * mDensity);
+    }
+
+    private int pxToDp(@Px float px) {
+        return (int) (px / mDensity);
+    }
+
+    private static final class RemoteViewsAndSizes {
+        final RemoteViews mRemoteViews;
+        final int mAvatarSize;
+
+        RemoteViewsAndSizes(RemoteViews remoteViews, int avatarSize) {
+            mRemoteViews = remoteViews;
+            mAvatarSize = avatarSize;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java b/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java
new file mode 100644
index 0000000..e5479ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.privacy.television;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+import androidx.annotation.Keep;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+
+/**
+ * Drawable that can go from being the background of the privacy icons to a small dot.
+ * The icons are not included.
+ */
+public class PrivacyChipDrawable extends Drawable {
+
+    private static final String TAG = PrivacyChipDrawable.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private float mWidth;
+    private float mHeight;
+    private float mMarginEnd;
+    private float mRadius;
+    private int mDotAlpha;
+    private int mBgAlpha;
+
+    private float mTargetWidth;
+    private final int mMinWidth;
+    private final int mIconWidth;
+    private final int mIconPadding;
+    private final int mBgWidth;
+    private final int mBgHeight;
+    private final int mBgRadius;
+    private final int mDotSize;
+
+    private final AnimatorSet mFadeIn;
+    private final AnimatorSet mFadeOut;
+    private final AnimatorSet mCollapse;
+    private final AnimatorSet mExpand;
+    private Animator mWidthAnimator;
+
+    private final Paint mChipPaint;
+    private final Paint mBgPaint;
+
+    private boolean mIsRtl;
+
+    private boolean mIsExpanded = true;
+
+    private PrivacyChipDrawableListener mListener;
+
+    interface PrivacyChipDrawableListener {
+        void onFadeOutFinished();
+    }
+
+    public PrivacyChipDrawable(Context context) {
+        mChipPaint = new Paint();
+        mChipPaint.setStyle(Paint.Style.FILL);
+        mChipPaint.setColor(context.getColor(R.color.privacy_circle));
+        mChipPaint.setAlpha(mDotAlpha);
+        mChipPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+
+        mBgPaint = new Paint();
+        mBgPaint.setStyle(Paint.Style.FILL);
+        mBgPaint.setColor(context.getColor(R.color.privacy_chip_dot_bg_tint));
+        mBgPaint.setAlpha(mBgAlpha);
+        mBgPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+
+        mBgWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_dot_bg_width);
+        mBgHeight = context.getResources().getDimensionPixelSize(
+                R.dimen.privacy_chip_dot_bg_height);
+        mBgRadius = context.getResources().getDimensionPixelSize(
+                R.dimen.privacy_chip_dot_bg_radius);
+
+        mMinWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_min_width);
+        mIconWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_icon_size);
+        mIconPadding = context.getResources().getDimensionPixelSize(
+                R.dimen.privacy_chip_icon_margin_in_between);
+        mDotSize = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_dot_size);
+
+        mWidth = mMinWidth;
+        mHeight = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_height);
+        mRadius = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_radius);
+
+        mExpand = (AnimatorSet) AnimatorInflater.loadAnimator(context,
+                R.anim.tv_privacy_chip_expand);
+        mExpand.setTarget(this);
+
+        mCollapse = (AnimatorSet) AnimatorInflater.loadAnimator(context,
+                R.anim.tv_privacy_chip_collapse);
+        mCollapse.setTarget(this);
+
+        mFadeIn = (AnimatorSet) AnimatorInflater.loadAnimator(context,
+                R.anim.tv_privacy_chip_fade_in);
+        mFadeIn.setTarget(this);
+
+        mFadeOut = (AnimatorSet) AnimatorInflater.loadAnimator(context,
+                R.anim.tv_privacy_chip_fade_out);
+        mFadeOut.setTarget(this);
+        mFadeOut.addListener(new Animator.AnimatorListener() {
+            private boolean mCancelled;
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mCancelled = false;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!mCancelled && mListener != null) {
+                    if (DEBUG) Log.d(TAG, "Fade-out complete");
+                    mListener.onFadeOutFinished();
+                }
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mCancelled = true;
+            }
+
+            @Override
+            public void onAnimationRepeat(Animator animation) {
+                // no-op
+            }
+        });
+    }
+
+    /**
+     * Pass null to remove listener.
+     */
+    public void setListener(@Nullable PrivacyChipDrawableListener listener) {
+        this.mListener = listener;
+    }
+
+    /**
+     * Call once the view that is showing the drawable is visible to start fading the chip in.
+     */
+    public void startInitialFadeIn() {
+        if (DEBUG) Log.d(TAG, "initial fade-in");
+        mFadeIn.start();
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        Rect bounds = getBounds();
+
+        int centerVertical = (bounds.bottom - bounds.top) / 2;
+        // Dot background
+        RectF bgBounds = new RectF(
+                mIsRtl ? bounds.left : bounds.right - mBgWidth,
+                centerVertical - mBgHeight / 2f,
+                mIsRtl ? bounds.left + mBgWidth : bounds.right,
+                centerVertical + mBgHeight / 2f);
+        if (DEBUG) Log.v(TAG, "bg: " + bgBounds.toShortString());
+        canvas.drawRoundRect(bgBounds, mBgRadius, mBgRadius, mBgPaint);
+
+        // Icon background / dot
+        RectF greenBounds = new RectF(
+                mIsRtl ? bounds.left + mMarginEnd : bounds.right - mWidth - mMarginEnd,
+                centerVertical - mHeight / 2,
+                mIsRtl ? bounds.left + mWidth + mMarginEnd : bounds.right - mMarginEnd,
+                centerVertical + mHeight / 2);
+        if (DEBUG) Log.v(TAG, "green: " + greenBounds.toShortString());
+        canvas.drawRoundRect(greenBounds, mRadius, mRadius, mChipPaint);
+    }
+
+    private void animateToNewTargetWidth(float width) {
+        if (DEBUG) Log.d(TAG, "new target width: " + width);
+        if (width != mTargetWidth) {
+            mTargetWidth = width;
+            Animator newWidthAnimator = ObjectAnimator.ofFloat(this, "width", mTargetWidth);
+            newWidthAnimator.start();
+            if (mWidthAnimator != null) {
+                mWidthAnimator.cancel();
+            }
+            mWidthAnimator = newWidthAnimator;
+        }
+    }
+
+    private void expand() {
+        if (DEBUG) Log.d(TAG, "expanding");
+        if (mIsExpanded) {
+            return;
+        }
+        mIsExpanded = true;
+
+        mExpand.start();
+        mCollapse.cancel();
+    }
+
+    /**
+     * Starts the animation to a dot.
+     */
+    public void collapse() {
+        if (DEBUG) Log.d(TAG, "collapsing");
+        if (!mIsExpanded) {
+            return;
+        }
+        mIsExpanded = false;
+
+        animateToNewTargetWidth(mDotSize);
+        mCollapse.start();
+        mExpand.cancel();
+    }
+
+    /**
+     * Fades out the view if 0 icons are to be shown, expands the chip if it has been collapsed and
+     * makes the width of the chip adjust to the amount of icons to be shown.
+     * Should not be called when only the order of the icons was changed as the chip will expand
+     * again without there being any real update.
+     *
+     * @param iconCount Can be 0 to fade out the chip.
+     */
+    public void updateIcons(int iconCount) {
+        if (DEBUG) Log.d(TAG, "updating icons: " + iconCount);
+
+        // calculate chip size and use it for end value of animation that is specified in code,
+        // not xml
+        if (iconCount == 0) {
+            // fade out if there are no icons
+            mFadeOut.start();
+
+            mWidthAnimator.cancel();
+            mFadeIn.cancel();
+            mExpand.cancel();
+            mCollapse.cancel();
+            return;
+        }
+
+        mFadeOut.cancel();
+        expand();
+        animateToNewTargetWidth(mMinWidth + (iconCount - 1) * (mIconWidth + mIconPadding));
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        setDotAlpha(alpha);
+        setBgAlpha(alpha);
+    }
+
+    @Override
+    public int getAlpha() {
+        return mDotAlpha;
+    }
+
+    /**
+     * Set alpha value the green part of the chip.
+     */
+    @Keep
+    public void setDotAlpha(int alpha) {
+        if (DEBUG) Log.v(TAG, "dot alpha updated to: " + alpha);
+        mDotAlpha = alpha;
+        mChipPaint.setAlpha(alpha);
+    }
+
+    @Keep
+    public int getDotAlpha() {
+        return mDotAlpha;
+    }
+
+    /**
+     * Set alpha value of the background of the chip.
+     */
+    @Keep
+    public void setBgAlpha(int alpha) {
+        if (DEBUG) Log.v(TAG, "bg alpha updated to: " + alpha);
+        mBgAlpha = alpha;
+        mBgPaint.setAlpha(alpha);
+    }
+
+    @Keep
+    public int getBgAlpha() {
+        return mBgAlpha;
+    }
+
+    @Override
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
+        // no-op
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    /**
+     * The radius of the green part of the chip, not the background.
+     */
+    @Keep
+    public void setRadius(float radius) {
+        mRadius = radius;
+        invalidateSelf();
+    }
+
+    /**
+     * @return The radius of the green part of the chip, not the background.
+     */
+    @Keep
+    public float getRadius() {
+        return mRadius;
+    }
+
+    /**
+     * Height of the green part of the chip, not including the background.
+     */
+    @Keep
+    public void setHeight(float height) {
+        mHeight = height;
+        invalidateSelf();
+    }
+
+    /**
+     * @return Height of the green part of the chip, not including the background.
+     */
+    @Keep
+    public float getHeight() {
+        return mHeight;
+    }
+
+    /**
+     * Width of the green part of the chip, not including the background.
+     */
+    @Keep
+    public void setWidth(float width) {
+        mWidth = width;
+        invalidateSelf();
+    }
+
+    /**
+     * @return Width of the green part of the chip, not including the background.
+     */
+    @Keep
+    public float getWidth() {
+        return mWidth;
+    }
+
+    /**
+     * Margin at the end of the green part of the chip, so that it will be placed in the middle of
+     * the rounded rectangle in the background.
+     */
+    @Keep
+    public void setMarginEnd(float marginEnd) {
+        mMarginEnd = marginEnd;
+        invalidateSelf();
+    }
+
+    /**
+     * @return Margin at the end of the green part of the chip, so that it will be placed in the
+     * middle of the rounded rectangle in the background.
+     */
+    @Keep
+    public float getMarginEnd() {
+        return mMarginEnd;
+    }
+
+    /**
+     * Sets the layout direction.
+     */
+    public void setRtl(boolean isRtl) {
+        mIsRtl = isRtl;
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
index 5ab7bd8..e4f5cde 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
@@ -25,9 +25,10 @@
 import android.annotation.UiThread;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -38,15 +39,20 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import androidx.annotation.NonNull;
+
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.privacy.PrivacyChipBuilder;
 import com.android.systemui.privacy.PrivacyItem;
 import com.android.systemui.privacy.PrivacyItemController;
+import com.android.systemui.privacy.PrivacyType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -56,9 +62,10 @@
  * recording audio, accessing the camera or accessing the location.
  */
 @SysUISingleton
-public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemController.Callback {
+public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemController.Callback,
+        PrivacyChipDrawable.PrivacyChipDrawableListener {
     private static final String TAG = "TvOngoingPrivacyChip";
-    static final boolean DEBUG = false;
+    private static final boolean DEBUG = false;
 
     // This title is used in CameraMicIndicatorsPermissionTest and
     // RecognitionServiceMicIndicatorTest.
@@ -68,7 +75,8 @@
     @IntDef(prefix = {"STATE_"}, value = {
             STATE_NOT_SHOWN,
             STATE_APPEARING,
-            STATE_SHOWN,
+            STATE_EXPANDED,
+            STATE_COLLAPSED,
             STATE_DISAPPEARING
     })
     public @interface State {
@@ -76,46 +84,58 @@
 
     private static final int STATE_NOT_SHOWN = 0;
     private static final int STATE_APPEARING = 1;
-    private static final int STATE_SHOWN = 2;
-    private static final int STATE_DISAPPEARING = 3;
+    private static final int STATE_EXPANDED = 2;
+    private static final int STATE_COLLAPSED = 3;
+    private static final int STATE_DISAPPEARING = 4;
 
-    private static final int ANIMATION_DURATION_MS = 200;
+    private static final int EXPANDED_DURATION_MS = 4000;
+    public final int mAnimationDurationMs;
 
     private final Context mContext;
     private final PrivacyItemController mPrivacyItemController;
 
-    private View mIndicatorView;
+    private ViewGroup mIndicatorView;
     private boolean mViewAndWindowAdded;
     private ObjectAnimator mAnimator;
 
     private boolean mMicCameraIndicatorFlagEnabled;
-    private boolean mLocationIndicatorEnabled;
-    private List<PrivacyItem> mPrivacyItems;
+    private boolean mAllIndicatorsEnabled;
+
+    @NonNull
+    private List<PrivacyItem> mPrivacyItems = Collections.emptyList();
 
     private LinearLayout mIconsContainer;
     private final int mIconSize;
     private final int mIconMarginStart;
 
+    private PrivacyChipDrawable mChipDrawable;
+
+    private final Handler mUiThreadHandler = new Handler(Looper.getMainLooper());
+    private final Runnable mCollapseRunnable = this::collapseChip;
+
     @State
     private int mState = STATE_NOT_SHOWN;
 
     @Inject
     public TvOngoingPrivacyChip(Context context, PrivacyItemController privacyItemController) {
         super(context);
-        Log.d(TAG, "Privacy chip running without id");
+        if (DEBUG) Log.d(TAG, "Privacy chip running");
         mContext = context;
         mPrivacyItemController = privacyItemController;
 
         Resources res = mContext.getResources();
-        mIconMarginStart = Math.round(res.getDimension(R.dimen.privacy_chip_icon_margin));
+        mIconMarginStart = Math.round(
+                res.getDimension(R.dimen.privacy_chip_icon_margin_in_between));
         mIconSize = res.getDimensionPixelSize(R.dimen.privacy_chip_icon_size);
 
+        mAnimationDurationMs = res.getInteger(R.integer.privacy_chip_animation_millis);
+
         mMicCameraIndicatorFlagEnabled = privacyItemController.getMicCameraAvailable();
-        mLocationIndicatorEnabled = privacyItemController.getLocationAvailable();
+        mAllIndicatorsEnabled = privacyItemController.getAllIndicatorsAvailable();
 
         if (DEBUG) {
             Log.d(TAG, "micCameraIndicators: " + mMicCameraIndicatorFlagEnabled);
-            Log.d(TAG, "locationIndicators: " + mLocationIndicatorEnabled);
+            Log.d(TAG, "allIndicators: " + mAllIndicatorsEnabled);
         }
     }
 
@@ -125,69 +145,145 @@
     }
 
     @Override
-    public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) {
+    public void onPrivacyItemsChanged(@NonNull List<PrivacyItem> privacyItems) {
         if (DEBUG) Log.d(TAG, "PrivacyItemsChanged");
-        mPrivacyItems = privacyItems;
-        updateUI();
+
+        List<PrivacyItem> updatedPrivacyItems = new ArrayList<>(privacyItems);
+        // Never show the location indicator on tv.
+        if (updatedPrivacyItems.removeIf(
+                privacyItem -> privacyItem.getPrivacyType() == PrivacyType.TYPE_LOCATION)) {
+            if (DEBUG) Log.v(TAG, "Removed the location item");
+        }
+
+        if (isChipDisabled()) {
+            fadeOutIndicator();
+            mPrivacyItems = updatedPrivacyItems;
+            return;
+        }
+
+        // Do they have the same elements? (order doesn't matter)
+        if (updatedPrivacyItems.size() == mPrivacyItems.size()
+                && mPrivacyItems.containsAll(updatedPrivacyItems)) {
+            if (DEBUG) Log.d(TAG, "List wasn't updated");
+            return;
+        }
+
+        mPrivacyItems = updatedPrivacyItems;
+        updateChip();
+    }
+
+    private void updateChip() {
+        if (DEBUG) Log.d(TAG, mPrivacyItems.size() + " privacy items");
+
+        if (mPrivacyItems.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "removing indicator (state: " + stateToString(mState) + ")");
+            fadeOutIndicator();
+            return;
+        }
+
+        if (DEBUG) Log.d(TAG, "Current state: " + stateToString(mState));
+        switch (mState) {
+            case STATE_NOT_SHOWN:
+                createAndShowIndicator();
+                break;
+            case STATE_APPEARING:
+            case STATE_EXPANDED:
+                updateIcons();
+                collapseLater();
+                break;
+            case STATE_COLLAPSED:
+            case STATE_DISAPPEARING:
+                mState = STATE_EXPANDED;
+                updateIcons();
+                animateIconAppearance();
+                break;
+        }
+    }
+
+    /**
+     * Collapse the chip EXPANDED_DURATION_MS from now.
+     */
+    private void collapseLater() {
+        mUiThreadHandler.removeCallbacks(mCollapseRunnable);
+        if (DEBUG) Log.d(TAG, "chip will collapse in " + EXPANDED_DURATION_MS + "ms");
+        mUiThreadHandler.postDelayed(mCollapseRunnable, EXPANDED_DURATION_MS);
+    }
+
+    private void collapseChip() {
+        if (DEBUG) Log.d(TAG, "collapseChip");
+
+        if (mState != STATE_EXPANDED) {
+            return;
+        }
+        mState = STATE_COLLAPSED;
+
+        if (mChipDrawable != null) {
+            mChipDrawable.collapse();
+        }
+        animateIconDisappearance();
     }
 
     @Override
     public void onFlagMicCameraChanged(boolean flag) {
         if (DEBUG) Log.d(TAG, "mic/camera indicators enabled: " + flag);
         mMicCameraIndicatorFlagEnabled = flag;
+        updateChipOnFlagChanged();
     }
 
     @Override
-    public void onFlagLocationChanged(boolean flag) {
-        if (DEBUG) Log.d(TAG, "location indicators enabled: " + flag);
-        mLocationIndicatorEnabled = flag;
+    public void onFlagAllChanged(boolean flag) {
+        if (DEBUG) Log.d(TAG, "all indicators enabled: " + flag);
+        mAllIndicatorsEnabled = flag;
+        updateChipOnFlagChanged();
     }
 
-    private void updateUI() {
-        if (DEBUG) Log.d(TAG, mPrivacyItems.size() + " privacy items");
+    private boolean isChipDisabled() {
+        return !(mMicCameraIndicatorFlagEnabled || mAllIndicatorsEnabled);
+    }
 
-        if ((mMicCameraIndicatorFlagEnabled || mLocationIndicatorEnabled)
-                && !mPrivacyItems.isEmpty()) {
-            if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) {
-                showIndicator();
-            } else {
-                if (DEBUG) Log.d(TAG, "only updating icons");
-                PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems);
-                setIcons(builder.generateIcons(), mIconsContainer);
-                mIconsContainer.requestLayout();
-            }
+    private void updateChipOnFlagChanged() {
+        if (isChipDisabled()) {
+            fadeOutIndicator();
         } else {
-            hideIndicatorIfNeeded();
+            updateChip();
         }
     }
 
     @UiThread
-    private void hideIndicatorIfNeeded() {
+    private void fadeOutIndicator() {
         if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) return;
 
+        mUiThreadHandler.removeCallbacks(mCollapseRunnable);
+
         if (mViewAndWindowAdded) {
             mState = STATE_DISAPPEARING;
-            animateDisappearance();
+            animateIconDisappearance();
         } else {
             // Appearing animation has not started yet, as we were still waiting for the View to be
             // laid out.
             mState = STATE_NOT_SHOWN;
             removeIndicatorView();
         }
+        if (mChipDrawable != null) {
+            mChipDrawable.updateIcons(0);
+        }
     }
 
     @UiThread
-    private void showIndicator() {
+    private void createAndShowIndicator() {
         mState = STATE_APPEARING;
 
+        if (mIndicatorView != null || mViewAndWindowAdded) {
+            removeIndicatorView();
+        }
+
         // Inflate the indicator view
-        mIndicatorView = LayoutInflater.from(mContext).inflate(
+        mIndicatorView = (ViewGroup) LayoutInflater.from(mContext).inflate(
                 R.layout.tv_ongoing_privacy_chip, null);
 
-        // 1. Set alpha to 0.
+        // 1. Set icon alpha to 0.
         // 2. Wait until the window is shown and the view is laid out.
         // 3. Start a "fade in" (alpha) animation.
-        mIndicatorView.setAlpha(0f);
         mIndicatorView
                 .getViewTreeObserver()
                 .addOnGlobalLayoutListener(
@@ -196,20 +292,35 @@
                             public void onGlobalLayout() {
                                 // State could have changed to NOT_SHOWN (if all the recorders are
                                 // already gone)
-                                if (mState != STATE_APPEARING) return;
+                                if (mState != STATE_APPEARING) {
+                                    return;
+                                }
 
                                 mViewAndWindowAdded = true;
                                 // Remove the observer
                                 mIndicatorView.getViewTreeObserver().removeOnGlobalLayoutListener(
                                         this);
 
-                                animateAppearance();
+                                animateIconAppearance();
+                                mChipDrawable.startInitialFadeIn();
                             }
                         });
 
+        final boolean isRtl = mContext.getResources().getConfiguration().getLayoutDirection()
+                == View.LAYOUT_DIRECTION_RTL;
+        if (DEBUG) Log.d(TAG, "is RTL: " + isRtl);
+
+        mChipDrawable = new PrivacyChipDrawable(mContext);
+        mChipDrawable.setListener(this);
+        mChipDrawable.setRtl(isRtl);
+        ImageView chipBackground = mIndicatorView.findViewById(R.id.chip_drawable);
+        if (chipBackground != null) {
+            chipBackground.setImageDrawable(mChipDrawable);
+        }
+
         mIconsContainer = mIndicatorView.findViewById(R.id.icons_container);
-        PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems);
-        setIcons(builder.generateIcons(), mIconsContainer);
+        mIconsContainer.setAlpha(0f);
+        updateIcons();
 
         final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                 WRAP_CONTENT,
@@ -217,19 +328,19 @@
                 WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                 PixelFormat.TRANSLUCENT);
-        layoutParams.gravity = Gravity.TOP | Gravity.END;
+        layoutParams.gravity = Gravity.TOP | (isRtl ? Gravity.LEFT : Gravity.RIGHT);
         layoutParams.setTitle(LAYOUT_PARAMS_TITLE);
         layoutParams.packageName = mContext.getPackageName();
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
         windowManager.addView(mIndicatorView, layoutParams);
-
     }
 
-    private void setIcons(List<Drawable> icons, ViewGroup iconsContainer) {
-        iconsContainer.removeAllViews();
+    private void updateIcons() {
+        List<Drawable> icons = new PrivacyChipBuilder(mContext, mPrivacyItems).generateIcons();
+        mIconsContainer.removeAllViews();
         for (int i = 0; i < icons.size(); i++) {
             Drawable icon = icons.get(i);
-            icon.mutate().setTint(Color.WHITE);
+            icon.mutate().setTint(mContext.getColor(R.color.privacy_icon_tint));
             ImageView imageView = new ImageView(mContext);
             imageView.setImageDrawable(icon);
             imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
@@ -241,22 +352,25 @@
                 imageView.setLayoutParams(layoutParams);
             }
         }
+        if (mChipDrawable != null) {
+            mChipDrawable.updateIcons(icons.size());
+        }
     }
 
-    private void animateAppearance() {
-        animateAlphaTo(1f);
+    private void animateIconAppearance() {
+        animateIconAlphaTo(1f);
     }
 
-    private void animateDisappearance() {
-        animateAlphaTo(0f);
+    private void animateIconDisappearance() {
+        animateIconAlphaTo(0f);
     }
 
-    private void animateAlphaTo(final float endValue) {
+    private void animateIconAlphaTo(float endValue) {
         if (mAnimator == null) {
             if (DEBUG) Log.d(TAG, "set up animator");
 
             mAnimator = new ObjectAnimator();
-            mAnimator.setTarget(mIndicatorView);
+            mAnimator.setTarget(mIconsContainer);
             mAnimator.setProperty(View.ALPHA);
             mAnimator.addListener(new AnimatorListenerAdapter() {
                 boolean mCancelled;
@@ -280,7 +394,7 @@
                     // and then onAnimationEnd(...). We, however, only want to proceed here if the
                     // animation ended "naturally".
                     if (!mCancelled) {
-                        onAnimationFinished();
+                        onIconAnimationFinished();
                     }
                 }
             });
@@ -289,19 +403,37 @@
             mAnimator.cancel();
         }
 
-        final float currentValue = mIndicatorView.getAlpha();
+        final float currentValue = mIconsContainer.getAlpha();
+        if (currentValue == endValue) {
+            if (DEBUG) Log.d(TAG, "alpha not changing");
+            return;
+        }
         if (DEBUG) Log.d(TAG, "animate alpha to " + endValue + " from " + currentValue);
 
-        mAnimator.setDuration((int) (Math.abs(currentValue - endValue) * ANIMATION_DURATION_MS));
+        mAnimator.setDuration(mAnimationDurationMs);
         mAnimator.setFloatValues(endValue);
         mAnimator.start();
     }
 
-    private void onAnimationFinished() {
-        if (DEBUG) Log.d(TAG, "onAnimationFinished");
+    @Override
+    public void onFadeOutFinished() {
+        if (DEBUG) Log.d(TAG, "drawable fade-out finished");
+
+        if (mState == STATE_DISAPPEARING) {
+            removeIndicatorView();
+            mState = STATE_NOT_SHOWN;
+        }
+    }
+
+    private void onIconAnimationFinished() {
+        if (DEBUG) Log.d(TAG, "onAnimationFinished (icon fade)");
+
+        if (mState == STATE_APPEARING || mState == STATE_EXPANDED) {
+            collapseLater();
+        }
 
         if (mState == STATE_APPEARING) {
-            mState = STATE_SHOWN;
+            mState = STATE_EXPANDED;
         } else if (mState == STATE_DISAPPEARING) {
             removeIndicatorView();
             mState = STATE_NOT_SHOWN;
@@ -312,14 +444,39 @@
         if (DEBUG) Log.d(TAG, "removeIndicatorView");
 
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
-        if (windowManager != null) {
+        if (windowManager != null && mIndicatorView != null) {
             windowManager.removeView(mIndicatorView);
         }
 
         mIndicatorView = null;
         mAnimator = null;
 
+        if (mChipDrawable != null) {
+            mChipDrawable.setListener(null);
+            mChipDrawable = null;
+        }
+
         mViewAndWindowAdded = false;
     }
 
+    /**
+     * Used in debug logs.
+     */
+    private String stateToString(@State int state) {
+        switch (state) {
+            case STATE_NOT_SHOWN:
+                return "NOT_SHOWN";
+            case STATE_APPEARING:
+                return "APPEARING";
+            case STATE_EXPANDED:
+                return "EXPANDED";
+            case STATE_COLLAPSED:
+                return "COLLAPSED";
+            case STATE_DISAPPEARING:
+                return "DISAPPEARING";
+            default:
+                return "INVALID";
+        }
+    }
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index edfbed0..6660081 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -297,7 +297,7 @@
                 // start margin of next page).
                 qsPanelController.setPageMargin(mSideMargins);
             } else if (view == mHeader) {
-                // No content padding for the header.
+                quickStatusBarHeaderController.setContentMargins(mContentPadding, mContentPadding);
             } else {
                 view.setPaddingRelative(
                         mContentPadding,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 2d0d87d..bcce87a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -46,6 +46,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
 
 public class QSDetail extends LinearLayout {
 
@@ -83,6 +84,8 @@
     private boolean mSwitchState;
     private QSFooter mFooter;
 
+    private NotificationsQuickSettingsContainer mContainer;
+
     public QSDetail(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
@@ -115,6 +118,10 @@
         mClipper = new QSDetailClipper(this);
     }
 
+    public void setContainer(NotificationsQuickSettingsContainer container) {
+        mContainer = container;
+    }
+
     /** */
     public void setQsPanel(QSPanelController panelController, QuickStatusBarHeader header,
             QSFooter footer) {
@@ -242,6 +249,9 @@
         }
         sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         animateDetailVisibleDiff(x, y, visibleDiff, listener);
+        if (mContainer != null) {
+            mContainer.setDetailShowing(showingDetail);
+        }
     }
 
     protected void animateDetailVisibleDiff(int x, int y, boolean visibleDiff, AnimatorListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 7b8a6a0..c28c649 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -293,6 +293,7 @@
     public void setContainer(ViewGroup container) {
         if (container instanceof NotificationsQuickSettingsContainer) {
             mQSCustomizerController.setContainer((NotificationsQuickSettingsContainer) container);
+            mQSDetail.setContainer((NotificationsQuickSettingsContainer) container);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 0bb0a3f..c70eaff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -425,7 +425,7 @@
             LinearLayout.LayoutParams layoutParams = (LayoutParams) hostView.getLayoutParams();
             layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
             layoutParams.width = horizontal ? 0 : ViewGroup.LayoutParams.MATCH_PARENT;
-            layoutParams.weight = horizontal ? 1.2f : 0;
+            layoutParams.weight = horizontal ? 1f : 0;
             // Add any bottom margin, such that the total spacing is correct. This is only
             // necessary if the view isn't horizontal, since otherwise the padding is
             // carried in the parent of this view (to ensure correct vertical alignment)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index cbdcad5..76076f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -177,7 +177,6 @@
         mView.onAttach(mIconManager, mQSExpansionPathInterpolator);
 
         mDemoModeController.addCallback(mDemoModeReceiver);
-        mHeaderQsPanelController.setContentMargins(0, 0);
     }
 
     @Override
@@ -253,6 +252,10 @@
         return mMicCameraIndicatorsEnabled || mLocationIndicatorsEnabled;
     }
 
+    public void setContentMargins(int marginStart, int marginEnd) {
+        mHeaderQsPanelController.setContentMargins(marginStart, marginEnd);
+    }
+
     private static class ClockDemoModeReceiver implements DemoMode {
         private Clock mClockView;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index c6b5eb7..5bb3413 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -291,19 +291,24 @@
                 ? res.getString(R.string.screenrecord_ongoing_screen_only)
                 : res.getString(R.string.screenrecord_ongoing_screen_and_audio);
 
-        Intent stopIntent = getNotificationIntent(this);
+        PendingIntent pendingIntent = PendingIntent.getService(
+                this,
+                REQUEST_CODE,
+                getNotificationIntent(this),
+                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+        Notification.Action stopAction = new Notification.Action.Builder(
+                Icon.createWithResource(this, R.drawable.ic_android),
+                getResources().getString(R.string.screenrecord_stop_label),
+                pendingIntent).build();
         Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                 .setSmallIcon(R.drawable.ic_screenrecord)
                 .setContentTitle(notificationTitle)
-                .setContentText(getResources().getString(R.string.screenrecord_stop_text))
                 .setUsesChronometer(true)
                 .setColorized(true)
                 .setColor(getResources().getColor(R.color.GM2_red_700))
                 .setOngoing(true)
                 .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
-                .setContentIntent(
-                        PendingIntent.getService(this, REQUEST_CODE, stopIntent,
-                                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+                .addAction(stopAction)
                 .addExtras(extras);
         startForeground(NOTIFICATION_RECORDING_ID, builder.build());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
index 4aead817f..55602a9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
@@ -111,30 +111,21 @@
     }
 
     /**
-     * Stores the given Bitmap to a temp file.
+     * Writes the given Bitmap to outputFile.
      */
-    ListenableFuture<File> exportAsTempFile(Executor executor, Bitmap bitmap) {
+    ListenableFuture<File> exportToRawFile(Executor executor, Bitmap bitmap,
+            final File outputFile) {
         return CallbackToFutureAdapter.getFuture(
                 (completer) -> {
                     executor.execute(() -> {
-                        File cachePath;
-                        try {
-                            cachePath = File.createTempFile("long_screenshot_cache_", ".tmp");
-                            try (FileOutputStream stream = new FileOutputStream(cachePath)) {
-                                bitmap.compress(mCompressFormat, mQuality, stream);
-                            } catch (IOException e) {
-                                if (cachePath.exists()) {
-                                    //noinspection ResultOfMethodCallIgnored
-                                    cachePath.delete();
-                                    cachePath = null;
-                                }
-                                completer.setException(e);
-                            }
-                            if (cachePath != null) {
-                                completer.set(cachePath);
-                            }
+                        try (FileOutputStream stream = new FileOutputStream(outputFile)) {
+                            bitmap.compress(mCompressFormat, mQuality, stream);
+                            completer.set(outputFile);
                         } catch (IOException e) {
-                            // Failed to create a new file
+                            if (outputFile.exists()) {
+                                //noinspection ResultOfMethodCallIgnored
+                                outputFile.delete();
+                            }
                             completer.setException(e);
                         }
                     });
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
index 730702e..51cc32a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
@@ -20,6 +20,7 @@
 import android.graphics.HardwareRenderer;
 import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.graphics.RenderNode;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
@@ -46,7 +47,6 @@
 
     private static final String TAG = "ImageTileSet";
 
-    private CallbackRegistry<OnBoundsChangedListener, ImageTileSet, Rect> mOnBoundsListeners;
     private CallbackRegistry<OnContentChangedListener, ImageTileSet, Rect> mContentListeners;
 
     @Inject
@@ -54,14 +54,6 @@
         mHandler = handler;
     }
 
-    interface OnBoundsChangedListener {
-        /**
-         * Reports an update to the bounding box that contains all active tiles. These are virtual
-         * (capture) coordinates which can be either negative or positive.
-         */
-        void onBoundsChanged(int left, int top, int right, int bottom);
-    }
-
     interface OnContentChangedListener {
         /**
          * Mark as dirty and rebuild display list.
@@ -70,25 +62,9 @@
     }
 
     private final List<ImageTile> mTiles = new ArrayList<>();
-    private final Rect mBounds = new Rect();
+    private final Region mRegion = new Region();
     private final Handler mHandler;
 
-    void addOnBoundsChangedListener(OnBoundsChangedListener listener) {
-        if (mOnBoundsListeners == null) {
-            mOnBoundsListeners = new CallbackRegistry<>(
-                    new NotifierCallback<OnBoundsChangedListener, ImageTileSet, Rect>() {
-                        @Override
-                        public void onNotifyCallback(OnBoundsChangedListener callback,
-                                ImageTileSet sender,
-                                int arg, Rect newBounds) {
-                            callback.onBoundsChanged(newBounds.left, newBounds.top, newBounds.right,
-                                    newBounds.bottom);
-                        }
-                    });
-        }
-        mOnBoundsListeners.add(listener);
-    }
-
     void addOnContentChangedListener(OnContentChangedListener listener) {
         if (mContentListeners == null) {
             mContentListeners = new CallbackRegistry<>(
@@ -110,14 +86,8 @@
             mHandler.post(() -> addTile(tile));
             return;
         }
-        final Rect newBounds = new Rect(mBounds);
-        final Rect newRect = tile.getLocation();
         mTiles.add(tile);
-        newBounds.union(newRect);
-        if (!newBounds.equals(mBounds)) {
-            mBounds.set(newBounds);
-            notifyBoundsChanged(mBounds);
-        }
+        mRegion.op(tile.getLocation(), mRegion, Region.Op.UNION);
         notifyContentChanged();
     }
 
@@ -127,12 +97,6 @@
         }
     }
 
-    private void notifyBoundsChanged(Rect bounds) {
-        if (mOnBoundsListeners != null) {
-            mOnBoundsListeners.notifyCallbacks(this, 0, bounds);
-        }
-    }
-
     /**
      * Returns a drawable to paint the combined contents of the tiles. Drawable dimensions are
      * zero-based and map directly to {@link #getLeft()}, {@link #getTop()}, {@link #getRight()},
@@ -153,6 +117,15 @@
         return mTiles.size();
     }
 
+    /**
+     * @return the bounding rect around any gaps in the tiles.
+     */
+    Rect getGaps() {
+        Region difference = new Region();
+        difference.op(mRegion.getBounds(), mRegion, Region.Op.DIFFERENCE);
+        return difference.getBounds();
+    }
+
     ImageTile get(int i) {
         return mTiles.get(i);
     }
@@ -182,41 +155,40 @@
     }
 
     int getLeft() {
-        return mBounds.left;
+        return mRegion.getBounds().left;
     }
 
     int getTop() {
-        return mBounds.top;
+        return mRegion.getBounds().top;
     }
 
     int getRight() {
-        return mBounds.right;
+        return mRegion.getBounds().right;
     }
 
     int getBottom() {
-        return mBounds.bottom;
+        return mRegion.getBounds().bottom;
     }
 
     int getWidth() {
-        return mBounds.width();
+        return mRegion.getBounds().width();
     }
 
     int getHeight() {
-        return mBounds.height();
+        return mRegion.getBounds().height();
     }
 
     void clear() {
         if (mTiles.isEmpty()) {
             return;
         }
-        mBounds.setEmpty();
+        mRegion.setEmpty();
         Iterator<ImageTile> i = mTiles.iterator();
         while (i.hasNext()) {
             ImageTile next = i.next();
             next.close();
             i.remove();
         }
-        notifyBoundsChanged(mBounds);
         notifyContentChanged();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index f571e41..07f6d36 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -228,8 +228,8 @@
                 });
 
         // Immediately export to temp image file for saved state
-        mCacheSaveFuture = mImageExporter.exportAsTempFile(mBackgroundExecutor,
-                mLongScreenshot.toBitmap());
+        mCacheSaveFuture = mImageExporter.exportToRawFile(mBackgroundExecutor,
+                mLongScreenshot.toBitmap(), new File(getCacheDir(), "long_screenshot_cache.png"));
         mCacheSaveFuture.addListener(() -> {
             try {
                 // Get the temp file path to persist, used in onSavedInstanceState
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 6690465..3c830cc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -453,14 +453,6 @@
                 mCornerSizeX / (mOrientationPortrait ? bounds.width() : bounds.height());
         final float currentScale = 1 / cornerScale;
 
-        mScreenshotPreview.setScaleX(currentScale);
-        mScreenshotPreview.setScaleY(currentScale);
-
-        if (mAccessibilityManager.isEnabled()) {
-            mDismissButton.setAlpha(0);
-            mDismissButton.setVisibility(View.VISIBLE);
-        }
-
         AnimatorSet dropInAnimation = new AnimatorSet();
         ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
         flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
@@ -491,6 +483,20 @@
 
         ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
         toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
+
+        toCorner.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mScreenshotPreview.setScaleX(currentScale);
+                mScreenshotPreview.setScaleY(currentScale);
+                mScreenshotPreview.setVisibility(View.VISIBLE);
+                if (mAccessibilityManager.isEnabled()) {
+                    mDismissButton.setAlpha(0);
+                    mDismissButton.setVisibility(View.VISIBLE);
+                }
+            }
+        });
+
         float xPositionPct =
                 SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
         float dismissPct =
@@ -534,13 +540,6 @@
             }
         });
 
-        toCorner.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mScreenshotPreview.setVisibility(View.VISIBLE);
-            }
-        });
-
         mScreenshotFlash.setAlpha(0f);
         mScreenshotFlash.setVisibility(View.VISIBLE);
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
index 94e3149..ce6e469 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
@@ -56,6 +56,7 @@
 public class ScrollCaptureClient {
     private static final int TILE_SIZE_PX_MAX = 4 * (1024 * 1024);
     private static final int TILES_PER_PAGE = 2; // increase once b/174571735 is addressed
+    private static final int MAX_TILES = 30;
 
     @VisibleForTesting
     static final int MATCH_ANY_TASK = ActivityTaskManager.INVALID_TASK_ID;
@@ -83,11 +84,12 @@
         int getMaxTiles();
 
         /**
-         * @return the maximum combined capture height for this session, in pixels.
+         * Target pixel height for acquisition this session. Session may yield more or less data
+         * than this, but acquiring this height is considered sufficient for completion.
+         *
+         * @return target height in pixels.
          */
-        default int getMaxHeight() {
-            return getMaxTiles() * getTileHeight();
-        }
+        int getTargetHeight();
 
         /**
          * @return the height of each image tile
@@ -234,11 +236,11 @@
         private final int mTileWidth;
         private Rect mRequestRect;
         private boolean mStarted;
+        private final int mTargetHeight;
 
         private ICancellationSignal mCancellationSignal;
         private final Rect mWindowBounds;
         private final Rect mBoundsInWindow;
-        private final int mMaxTiles;
 
         private Completer<Session> mStartCompleter;
         private Completer<CaptureResult> mTileRequestCompleter;
@@ -256,7 +258,7 @@
 
             mTileWidth = mBoundsInWindow.width();
             mTileHeight = pxPerTile / mBoundsInWindow.width();
-            mMaxTiles = (int) Math.ceil(maxPages * TILES_PER_PAGE);
+            mTargetHeight = (int) (mBoundsInWindow.height() * maxPages);
 
             if (DEBUG_SCROLL) {
                 Log.d(TAG, "boundsInWindow: " + mBoundsInWindow);
@@ -285,7 +287,7 @@
 
         private void start(Completer<Session> completer) {
             mReader = ImageReader.newInstance(mTileWidth, mTileHeight, PixelFormat.RGBA_8888,
-                    mMaxTiles, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
+                    MAX_TILES, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
             mStartCompleter = completer;
             try {
                 mCancellationSignal = mConnection.startCapture(mReader.getSurface(), this);
@@ -410,8 +412,13 @@
         }
 
         @Override
+        public int getTargetHeight() {
+            return mTargetHeight;
+        }
+
+        @Override
         public int getMaxTiles() {
-            return mMaxTiles;
+            return MAX_TILES;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index bbcfdbd..4c1f6a1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -199,22 +199,20 @@
         Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN")
                 + " finish on boundary: " + mFinishOnBoundary);
         boolean emptyResult = result.captured.height() == 0;
-        boolean partialResult = !emptyResult
-                && result.captured.height() < result.requested.height();
-        boolean finish = false;
 
         if (emptyResult) {
             // Potentially reached a vertical boundary. Extend in the other direction.
             if (mFinishOnBoundary) {
-                Log.d(TAG, "Partial/empty: finished!");
-                finish = true;
+                Log.d(TAG, "Empty: finished!");
+                finishCapture();
+                return;
             } else {
                 // We hit a boundary, clear the tiles, capture everything in the opposite direction,
                 // then finish.
                 mImageTileSet.clear();
                 mFinishOnBoundary = true;
                 mScrollingUp = !mScrollingUp;
-                Log.d(TAG, "Partial/empty: cleared, switch direction to finish");
+                Log.d(TAG, "Empty: cleared, switch direction to finish");
             }
         } else {
             // Got a non-empty result, but may already have enough bitmap data now
@@ -223,12 +221,14 @@
                 Log.d(TAG, "Hit max tiles: finished");
                 // If we ever hit the max tiles, we've got enough bitmap data to finish
                 // (even if we weren't sure we'd finish on this pass).
-                finish = true;
+                finishCapture();
+                return;
             } else {
                 if (mScrollingUp && !mFinishOnBoundary) {
                     // During the initial scroll up, we only want to acquire the portion described
                     // by IDEAL_PORTION_ABOVE.
-                    if (expectedTiles >= mSession.getMaxTiles() * IDEAL_PORTION_ABOVE) {
+                    if (mImageTileSet.getHeight() + result.captured.height()
+                            >= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) {
                         Log.d(TAG, "Hit ideal portion above: clear and switch direction");
                         // We got enough above the start point, now see how far down it can go.
                         mImageTileSet.clear();
@@ -246,15 +246,15 @@
                 + " - " +  mImageTileSet.getRight() + "," + mImageTileSet.getBottom()
                 + " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")");
 
-
-        // Stop when "too tall"
-        if (mImageTileSet.getHeight() > MAX_HEIGHT) {
-            Log.d(TAG, "Max height reached.");
-            finish = true;
+        Rect gapBounds = mImageTileSet.getGaps();
+        if (!gapBounds.isEmpty()) {
+            Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top);
+            requestNextTile(gapBounds.top);
+            return;
         }
 
-        if (finish) {
-            Log.d(TAG, "Stop.");
+        if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) {
+            Log.d(TAG, "Target height reached.");
             finishCapture();
             return;
         }
@@ -268,8 +268,8 @@
                     : result.requested.bottom;
         } else {
             nextTop = (mScrollingUp)
-                    ? result.captured.top - mSession.getTileHeight()
-                    : result.captured.bottom;
+                    ? mImageTileSet.getTop() - mSession.getTileHeight()
+                    : mImageTileSet.getBottom();
         }
         requestNextTile(nextTop);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
index 06c1c6f..a79316d 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
@@ -32,6 +32,7 @@
 import com.android.internal.app.AlertActivity
 import com.android.internal.widget.DialogTitle
 import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -46,13 +47,15 @@
 class SensorUseStartedActivity @Inject constructor(
     private val sensorPrivacyController: IndividualSensorPrivacyController,
     private val keyguardStateController: KeyguardStateController,
-    private val keyguardDismissUtil: KeyguardDismissUtil
+    private val keyguardDismissUtil: KeyguardDismissUtil,
+    @Background private val bgHandler: Handler
 ) : AlertActivity(), DialogInterface.OnClickListener {
 
     companion object {
         private val LOG_TAG = SensorUseStartedActivity::class.java.simpleName
 
         private const val SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS = 2000L
+        private const val UNLOCK_DELAY_MILLIS = 200L
 
         private const val CAMERA = SensorPrivacyManager.Sensors.CAMERA
         private const val MICROPHONE = SensorPrivacyManager.Sensors.MICROPHONE
@@ -179,9 +182,12 @@
             BUTTON_POSITIVE -> {
                 if (keyguardStateController.isMethodSecure && keyguardStateController.isShowing) {
                     keyguardDismissUtil.executeWhenUnlocked({
-                        disableSensorPrivacy()
+                        bgHandler.postDelayed({
+                            disableSensorPrivacy()
+                        }, UNLOCK_DELAY_MILLIS)
+
                         false
-                    }, false, false)
+                    }, false, true)
                 } else {
                     disableSensorPrivacy()
                 }
@@ -201,7 +207,7 @@
             sensorPrivacyController
                     .suppressSensorPrivacyReminders(sensorUsePackageName, false)
         } else {
-            Handler(mainLooper).postDelayed({
+            bgHandler.postDelayed({
                 sensorPrivacyController
                         .suppressSensorPrivacyReminders(sensorUsePackageName, false)
             }, SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS)
@@ -218,7 +224,12 @@
     }
 
     private fun disableSensorPrivacy() {
-        sensorPrivacyController.setSensorBlocked(sensor, false)
+        if (sensor == ALL_SENSORS) {
+            sensorPrivacyController.setSensorBlocked(MICROPHONE, false)
+            sensorPrivacyController.setSensorBlocked(CAMERA, false)
+        } else {
+            sensorPrivacyController.setSensorBlocked(sensor, false)
+        }
         unsuppressImmediately = true
         setResult(RESULT_OK)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java
new file mode 100644
index 0000000..9d101ef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.sensorprivacy.television;
+
+import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
+import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE;
+
+import android.hardware.SensorPrivacyManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
+import com.android.systemui.tv.TvBottomSheetActivity;
+
+import javax.inject.Inject;
+
+/**
+ * Bottom sheet that is shown when the camera/mic sensors are blocked by the global toggle and
+ * allows the user to re-enable them.
+ */
+public class TvUnblockSensorActivity extends TvBottomSheetActivity {
+
+    private static final String TAG = TvUnblockSensorActivity.class.getSimpleName();
+
+    private static final int ALL_SENSORS = Integer.MAX_VALUE;
+    private int mSensor = -1;
+
+    private final IndividualSensorPrivacyController mSensorPrivacyController;
+    private IndividualSensorPrivacyController.Callback mSensorPrivacyCallback;
+
+    @Inject
+    public TvUnblockSensorActivity(
+            IndividualSensorPrivacyController individualSensorPrivacyController) {
+        mSensorPrivacyController = individualSensorPrivacyController;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        boolean allSensors = getIntent().getBooleanExtra(SensorPrivacyManager.EXTRA_ALL_SENSORS,
+                false);
+        if (allSensors) {
+            mSensor = ALL_SENSORS;
+        } else {
+            mSensor = getIntent().getIntExtra(SensorPrivacyManager.EXTRA_SENSOR, -1);
+        }
+
+        if (mSensor == -1) {
+            Log.v(TAG, "Invalid extras");
+            finish();
+            return;
+        }
+
+        mSensorPrivacyCallback = (sensor, blocked) -> {
+            if (mSensor == ALL_SENSORS) {
+                if (!mSensorPrivacyController.isSensorBlocked(CAMERA)
+                        && !mSensorPrivacyController.isSensorBlocked(MICROPHONE)) {
+                    finish();
+                }
+            } else if (this.mSensor == sensor && !blocked) {
+                finish();
+            }
+        };
+
+        initUI();
+    }
+
+    private void initUI() {
+        TextView title = findViewById(R.id.bottom_sheet_title);
+        TextView content = findViewById(R.id.bottom_sheet_body);
+        ImageView icon = findViewById(R.id.bottom_sheet_icon);
+        // mic icon if both icons are shown
+        ImageView secondIcon = findViewById(R.id.bottom_sheet_second_icon);
+        Button unblockButton = findViewById(R.id.bottom_sheet_positive_button);
+        Button cancelButton = findViewById(R.id.bottom_sheet_negative_button);
+
+        switch (mSensor) {
+            case MICROPHONE:
+                title.setText(R.string.sensor_privacy_start_use_mic_dialog_title);
+                content.setText(R.string.sensor_privacy_start_use_mic_dialog_content);
+                icon.setImageResource(com.android.internal.R.drawable.perm_group_microphone);
+                secondIcon.setVisibility(View.GONE);
+                break;
+            case CAMERA:
+                title.setText(R.string.sensor_privacy_start_use_camera_dialog_title);
+                content.setText(R.string.sensor_privacy_start_use_camera_dialog_content);
+                icon.setImageResource(com.android.internal.R.drawable.perm_group_camera);
+                secondIcon.setVisibility(View.GONE);
+                break;
+            case ALL_SENSORS:
+            default:
+                title.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_title);
+                content.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_content);
+                icon.setImageResource(com.android.internal.R.drawable.perm_group_camera);
+                secondIcon.setImageResource(com.android.internal.R.drawable.perm_group_microphone);
+                break;
+        }
+        unblockButton.setText(
+                com.android.internal.R.string.sensor_privacy_start_use_dialog_turn_on_button);
+        unblockButton.setOnClickListener(v -> {
+            if (mSensor == ALL_SENSORS) {
+                mSensorPrivacyController.setSensorBlocked(CAMERA, false);
+                mSensorPrivacyController.setSensorBlocked(MICROPHONE, false);
+            } else {
+                mSensorPrivacyController.setSensorBlocked(mSensor, false);
+            }
+        });
+
+        cancelButton.setText(android.R.string.cancel);
+        cancelButton.setOnClickListener(v -> finish());
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mSensorPrivacyController.addCallback(mSensorPrivacyCallback);
+    }
+
+    @Override
+    public void onPause() {
+        mSensorPrivacyController.removeCallback(mSensorPrivacyCallback);
+        super.onPause();
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index ce796d9..89dda9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -22,6 +22,7 @@
 import android.content.res.Resources
 import android.util.IndentingPrintWriter
 import android.util.MathUtils
+import android.view.CrossWindowBlurListeners
 import android.view.SurfaceControl
 import android.view.ViewRootImpl
 import androidx.annotation.VisibleForTesting
@@ -37,6 +38,7 @@
 @SysUISingleton
 open class BlurUtils @Inject constructor(
     @Main private val resources: Resources,
+    private val crossWindowBlurListeners: CrossWindowBlurListeners,
     dumpManager: DumpManager
 ) : Dumpable {
     val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
@@ -97,7 +99,8 @@
      * @return {@code true} when supported.
      */
     open fun supportsBlursOnWindows(): Boolean {
-        return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx()
+        return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx() &&
+                crossWindowBlurListeners.isCrossWindowBlurEnabled()
     }
 
     override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 4a4e990..6f4a73e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -18,6 +18,7 @@
 import com.android.systemui.Gefingerpoken
 import com.android.systemui.R
 import com.android.systemui.animation.Interpolators
+import com.android.systemui.biometrics.UdfpsKeyguardViewController
 import com.android.systemui.classifier.Classifier
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
@@ -109,6 +110,11 @@
     private var nextHideKeyguardNeedsNoAnimation = false
 
     /**
+     * The udfpsKeyguardViewController if it exists.
+     */
+    var udfpsKeyguardViewController: UdfpsKeyguardViewController? = null
+
+    /**
      * The touch helper responsible for the drag down animation.
      */
     val touchHelper = DragDownHelper(falsingManager, falsingCollector, this, context)
@@ -291,6 +297,7 @@
                     // Fade out all content only visible on the lockscreen
                     notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
                     depthController.transitionToFullShadeProgress = scrimProgress
+                    udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 8900551..f03a9a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -96,6 +96,15 @@
     var globalActionsSpring = DepthAnimation()
     var showingHomeControls: Boolean = false
 
+    @VisibleForTesting
+    var brightnessMirrorSpring = DepthAnimation()
+    var brightnessMirrorVisible: Boolean = false
+        set(value) {
+            field = value
+            brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f)
+                else 0)
+        }
+
     var qsPanelExpansion = 0f
         set(value) {
             if (field == value) return
@@ -186,13 +195,16 @@
         var blur = max(shadeRadius.toInt(), globalActionsRadius)
 
         // Make blur be 0 if it is necessary to stop blur effect.
-        if (scrimsVisible) {
+        if (scrimsVisible || !blurUtils.supportsBlursOnWindows()) {
             blur = 0
         }
+        val zoomOut = blurUtils.ratioOfBlurRadius(blur)
+
+        // Brightness slider removes blur, but doesn't affect zooms
+        blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt()
 
         val opaque = scrimsVisible && !ignoreShadeBlurUntilHidden
         blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque)
-        val zoomOut = blurUtils.ratioOfBlurRadius(blur)
         try {
             if (root.isAttachedToWindow && root.windowToken != null) {
                 wallpaperManager.setWallpaperZoomOut(root.windowToken, zoomOut)
@@ -260,6 +272,7 @@
                 shadeSpring.finishIfRunning()
                 shadeAnimation.finishIfRunning()
                 globalActionsSpring.finishIfRunning()
+                brightnessMirrorSpring.finishIfRunning()
             }
         }
 
@@ -425,6 +438,7 @@
             it.println("shadeRadius: ${shadeSpring.radius}")
             it.println("shadeAnimation: ${shadeAnimation.radius}")
             it.println("globalActionsRadius: ${globalActionsSpring.radius}")
+            it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
             it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
             it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden")
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
index f1479a1..f19cf5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
@@ -22,11 +22,27 @@
     )
 
     var startTranslationZ = 0f
+
+    /**
+     * The top position of the notification at the start of the animation. This is needed in order
+     * to keep the notification at its place when launching a notification that is clipped rounded.
+     */
+    var startNotificationTop = 0f
     var startClipTopAmount = 0
     var parentStartClipTopAmount = 0
     var progress = 0f
     var linearProgress = 0f
 
+    /**
+     * The rounded top clipping at the beginning.
+     */
+    var startRoundedTopClipping = 0
+
+    /**
+     * The rounded top clipping of the parent notification at the start.
+     */
+    var parentStartRoundedTopClipping = 0
+
     override val topChange: Int
         get() {
             // We need this compensation to ensure that the QS moves in sync.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index c248670..1bbef25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -40,6 +40,11 @@
     private val headsUpManager: HeadsUpManagerPhone,
     private val notification: ExpandableNotificationRow
 ) : ActivityLaunchAnimator.Controller {
+
+    companion object {
+        const val ANIMATION_DURATION_TOP_ROUNDING = 100L
+    }
+
     private val notificationEntry = notification.entry
     private val notificationKey = notificationEntry.sbn.key
 
@@ -54,18 +59,37 @@
         val height = max(0, notification.actualHeight - notification.clipBottomAmount)
         val location = notification.locationOnScreen
 
+        val clipStartLocation = notificationListContainer.getTopClippingStartLocation()
+        val roundedTopClipping = Math.max(clipStartLocation - location[1], 0)
+        val windowTop = location[1] + roundedTopClipping
+        val topCornerRadius = if (roundedTopClipping > 0) {
+            // Because the rounded Rect clipping is complex, we start the top rounding at
+            // 0, which is pretty close to matching the real clipping.
+            // We'd have to clipOut the overlaid drawable too with the outer rounded rect in case
+            // if we'd like to have this perfect, but this is close enough.
+            0f
+        } else {
+            notification.currentBackgroundRadiusTop
+        }
         val params = ExpandAnimationParameters(
-                top = location[1],
+                top = windowTop,
                 bottom = location[1] + height,
                 left = location[0],
                 right = location[0] + notification.width,
-                topCornerRadius = notification.currentBackgroundRadiusTop,
+                topCornerRadius = topCornerRadius,
                 bottomCornerRadius = notification.currentBackgroundRadiusBottom
         )
 
         params.startTranslationZ = notification.translationZ
+        params.startNotificationTop = notification.translationY
+        params.startRoundedTopClipping = roundedTopClipping
         params.startClipTopAmount = notification.clipTopAmount
         if (notification.isChildInGroup) {
+            params.startNotificationTop += notification.notificationParent.translationY
+            val parentRoundedClip = Math.max(clipStartLocation
+                - notification.notificationParent.locationOnScreen[1], 0)
+            params.parentStartRoundedTopClipping = parentRoundedClip
+
             val parentClip = notification.notificationParent.clipTopAmount
             params.parentStartClipTopAmount = parentClip
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 9d56e9b..93166f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -35,6 +35,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.AnimationDrawable;
@@ -85,6 +86,7 @@
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
+import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
@@ -133,7 +135,7 @@
 
     private boolean mUpdateBackgroundOnUpdate;
     private boolean mNotificationTranslationFinished = false;
-    private ArrayList<MenuItem> mSnoozedMenuItems;
+    private boolean mIsSnoozed;
 
     /**
      * Listener for when {@link ExpandableNotificationRow} is laid out.
@@ -252,6 +254,7 @@
     private OnExpandClickListener mOnExpandClickListener;
     private View.OnClickListener mOnAppClickListener;
     private View.OnClickListener mOnFeedbackClickListener;
+    private Path mExpandingClipPath;
 
     // Listener will be called when receiving a long click event.
     // Use #setLongPressPosition to optionally assign positional data with the long press.
@@ -836,6 +839,7 @@
     public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {
         if (mExpandAnimationRunning && !isChildInGroup && mNotificationParent != null) {
             mNotificationParent.setChildIsExpanding(false);
+            mNotificationParent.setExpandingClipPath(null);
             mNotificationParent.setExtraWidthForClipping(0.0f);
             mNotificationParent.setMinimumHeightForClipping(0);
         }
@@ -1105,8 +1109,7 @@
                     false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
                     false /* resetMenu */);
             mNotificationGutsManager.openGuts(this, 0, 0, item);
-            mSnoozedMenuItems = mMenuRow.getMenuItems(mMenuRow.getMenuView().getContext());
-            mMenuRow.resetMenu();
+            mIsSnoozed = true;
         };
     }
 
@@ -1821,10 +1824,7 @@
 
     void onGutsClosed() {
         updateContentAccessibilityImportanceForGuts(true /* isEnabled */);
-        if (mSnoozedMenuItems != null && mSnoozedMenuItems.size() > 0) {
-            mMenuRow.setMenuItems(mSnoozedMenuItems);
-            mSnoozedMenuItems = null;
-        }
+        mIsSnoozed = false;
     }
 
     /**
@@ -2036,7 +2036,22 @@
         setTranslationZ(translationZ);
         float extraWidthForClipping = params.getWidth() - getWidth();
         setExtraWidthForClipping(extraWidthForClipping);
-        int top = params.getTop();
+        int top;
+        if (params.getStartRoundedTopClipping() > 0) {
+            // If we were clipping initially, let's interpolate from the start position to the
+            // top. Otherwise, we just take the top directly.
+            float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
+                    params.getProgress(0,
+                            NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
+            float startTop = params.getStartNotificationTop();
+            top = (int) Math.min(MathUtils.lerp(startTop,
+                    params.getTop(), expandProgress),
+                    startTop);
+        } else {
+            top = params.getTop();
+        }
+        int actualHeight = params.getBottom() - top;
+        setActualHeight(actualHeight);
         int startClipTopAmount = params.getStartClipTopAmount();
         int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, params.getProgress());
         if (mNotificationParent != null) {
@@ -2065,13 +2080,12 @@
             setClipTopAmount(clipTopAmount);
         }
         setTranslationY(top);
-        setActualHeight(params.getHeight());
 
         mTopRoundnessDuringExpandAnimation = params.getTopCornerRadius() / mOutlineRadius;
         mBottomRoundnessDuringExpandAnimation = params.getBottomCornerRadius() / mOutlineRadius;
         invalidateOutline();
 
-        mBackgroundNormal.setExpandAnimationParams(params);
+        mBackgroundNormal.setExpandAnimationSize(params.getWidth(), actualHeight);
     }
 
     public void setExpandAnimationRunning(boolean expandAnimationRunning) {
@@ -2468,7 +2482,8 @@
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         int intrinsicBefore = getIntrinsicHeight();
         super.onLayout(changed, left, top, right, bottom);
-        if (intrinsicBefore != getIntrinsicHeight() && intrinsicBefore != 0) {
+        if (intrinsicBefore != getIntrinsicHeight()
+                && (intrinsicBefore != 0 || getActualHeight() > 0)) {
             notifyHeightChanged(true  /* needsAnimation */);
         }
         if (mMenuRow != null && mMenuRow.getMenuView() != null) {
@@ -2981,7 +2996,7 @@
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
         info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
-        if (canViewBeDismissed()) {
+        if (canViewBeDismissed() && !mIsSnoozed) {
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
         }
         boolean expandable = shouldShowPublic();
@@ -2997,7 +3012,7 @@
                 isExpanded = isExpanded();
             }
         }
-        if (expandable) {
+        if (expandable && !mIsSnoozed) {
             if (isExpanded) {
                 info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
             } else {
@@ -3085,6 +3100,26 @@
         return super.childNeedsClipping(child);
     }
 
+    /**
+     * Set a clip path to be set while expanding the notification. This is needed to nicely
+     * clip ourselves during the launch if we were clipped rounded in the beginning
+     */
+    public void setExpandingClipPath(Path path) {
+        mExpandingClipPath = path;
+        invalidate();
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        canvas.save();
+        if (mExpandingClipPath != null && (mExpandAnimationRunning || mChildIsExpanding)) {
+            // If we're launching a notification, let's clip if a clip rounded to the clipPath
+            canvas.clipPath(mExpandingClipPath);
+        }
+        super.dispatchDraw(canvas);
+        canvas.restore();
+    }
+
     @Override
     protected void applyRoundness() {
         super.applyRoundness();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 754de58..0f615aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -240,10 +240,10 @@
         invalidate();
     }
 
-    /** Set the current expand animation parameters. */
-    public void setExpandAnimationParams(ExpandAnimationParameters params) {
-        mActualHeight = params.getHeight();
-        mActualWidth = params.getWidth();
+    /** Set the current expand animation size. */
+    public void setExpandAnimationSize(int actualWidth, int actualHeight) {
+        mActualHeight = actualHeight;
+        mActualWidth = actualWidth;
         invalidate();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 26606cd..197920f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -72,8 +72,6 @@
     private boolean mUnlockHintRunning;
     private boolean mQsCustomizerShowing;
     private int mIntrinsicPadding;
-    private int mExpandAnimationTopChange;
-    private ExpandableNotificationRow mExpandingNotification;
     private float mHideAmount;
     private boolean mAppearing;
     private float mPulseHeight = MAX_PULSE_HEIGHT;
@@ -518,22 +516,6 @@
         return isDozing() && !isPulsing(row.getEntry());
     }
 
-    public void setExpandAnimationTopChange(int expandAnimationTopChange) {
-        mExpandAnimationTopChange = expandAnimationTopChange;
-    }
-
-    public void setExpandingNotification(ExpandableNotificationRow row) {
-        mExpandingNotification = row;
-    }
-
-    public ExpandableNotificationRow getExpandingNotification() {
-        return mExpandingNotification;
-    }
-
-    public int getExpandAnimationTopChange() {
-        return mExpandAnimationTopChange;
-    }
-
     /**
      * @return {@code true } when shade is completely hidden: in AOD, ambient display or when
      * bypassing.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 2a2e733f7..7a5c188 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -200,4 +200,11 @@
     default void setWillExpand(boolean willExpand) {}
 
     void setNotificationActivityStarter(NotificationActivityStarter notificationActivityStarter);
+
+    /**
+     * @return the start location where we start clipping notifications.
+     */
+    default int getTopClippingStartLocation() {
+        return 0;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 9ba04bf..4e6d376 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -77,6 +77,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.CommandQueue;
@@ -90,6 +91,7 @@
 import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
 import com.android.systemui.statusbar.notification.FakeShadowView;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
@@ -139,6 +141,9 @@
     // adb shell setprop persist.debug.nssl true && adb reboot
     private static final boolean DEBUG = SystemProperties.getBoolean("persist.debug.nssl",
             false /* default */);
+    // TODO(b/187291379) disable again before release
+    private static final boolean DEBUG_REMOVE_ANIMATION = SystemProperties.getBoolean(
+            "persist.debug.nssl.dismiss", true /* default */);
 
     private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
     private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
@@ -471,6 +476,12 @@
     private final Path mRoundedClipPath = new Path();
 
     /**
+     * The clip Path used to clip the launching notification. This may be different
+     * from the normal path, as the views launch animation could start clipped.
+     */
+    private final Path mLaunchedNotificationClipPath = new Path();
+
+    /**
      * Should we use rounded rect clipping right now
      */
     private boolean mShouldUseRoundedRectClipping = false;
@@ -493,6 +504,26 @@
     private boolean mLaunchingNotification;
 
     /**
+     * Does the launching notification need to be clipped
+     */
+    private boolean mLaunchingNotificationNeedsToBeClipped;
+
+    /**
+     * The current launch animation params when launching a notification
+     */
+    private ExpandAnimationParameters mLaunchAnimationParams;
+
+    /**
+     * Corner radii of the launched notification if it's clipped
+     */
+    private float[] mLaunchedNotificationRadii = new float[8];
+
+    /**
+     * The notification that is being launched currently.
+     */
+    private ExpandableNotificationRow mExpandingNotificationRow;
+
+    /**
      * Do notifications dismiss with normal transitioning
      */
     private boolean mDismissUsingRowTranslationX = true;
@@ -2647,7 +2678,17 @@
      */
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     boolean generateRemoveAnimation(ExpandableView child) {
+        String key = "";
+        if (DEBUG_REMOVE_ANIMATION) {
+            if (child instanceof ExpandableNotificationRow) {
+                key = ((ExpandableNotificationRow) child).getEntry().getKey();
+            }
+            Log.d(TAG, "generateRemoveAnimation " + key);
+        }
         if (removeRemovedChildFromHeadsUpChangeAnimations(child)) {
+            if (DEBUG_REMOVE_ANIMATION) {
+                Log.d(TAG, "removedBecauseOfHeadsUp " + key);
+            }
             mAddedHeadsUpChildren.remove(child);
             return false;
         }
@@ -2656,8 +2697,17 @@
             mClearTransientViewsWhenFinished.add(child);
             return true;
         }
+        if (DEBUG_REMOVE_ANIMATION) {
+            Log.d(TAG, "generateRemove " + key
+                    + "\nmIsExpanded " + mIsExpanded
+                    + "\nmAnimationsEnabled " + mAnimationsEnabled
+                    + "\n!invisible group " + !isChildInInvisibleGroup(child));
+        }
         if (mIsExpanded && mAnimationsEnabled && !isChildInInvisibleGroup(child)) {
             if (!mChildrenToAddAnimated.contains(child)) {
+                if (DEBUG_REMOVE_ANIMATION) {
+                    Log.d(TAG, "needsAnimation = true " + key);
+                }
                 // Generate Animations
                 mChildrenToRemoveAnimated.add(child);
                 mNeedsAnimation = true;
@@ -2679,7 +2729,7 @@
     /**
      * Remove a removed child view from the heads up animations if it was just added there
      *
-     * @return whether any child was removed from the list to animate
+     * @return whether any child was removed from the list to animate and the view was just added
      */
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     private boolean removeRemovedChildFromHeadsUpChangeAnimations(View child) {
@@ -2698,7 +2748,7 @@
             ((ExpandableNotificationRow) child).setHeadsUpAnimatingAway(false);
         }
         mTmpList.clear();
-        return hasAddEvent;
+        return hasAddEvent && mAddedHeadsUpChildren.contains(child);
     }
 
     // TODO (b/162832756): remove since this won't happen in new pipeline (we prune groups in
@@ -2749,6 +2799,9 @@
      * @return the amount of scrolling needed to start clipping notifications.
      */
     private int getScrollAmountToScrollBoundary() {
+        if (mShouldUseSplitNotificationShade) {
+            return mSidePaddings;
+        }
         return mTopPadding - mQsScrollBoundaryPosition;
     }
 
@@ -2892,7 +2945,16 @@
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     void setExpandingNotification(ExpandableNotificationRow row) {
-        mAmbientState.setExpandingNotification(row);
+        if (mExpandingNotificationRow != null && row == null) {
+            // Let's unset the clip path being set during launch
+            mExpandingNotificationRow.setExpandingClipPath(null);
+            ExpandableNotificationRow parent = mExpandingNotificationRow.getNotificationParent();
+            if (parent != null) {
+                parent.setExpandingClipPath(null);
+            }
+        }
+        mExpandingNotificationRow = row;
+        updateLaunchedNotificationClipPath();
         requestChildrenUpdate();
     }
 
@@ -2902,10 +2964,10 @@
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void applyExpandAnimationParams(ExpandAnimationParameters params) {
-        mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange());
-
-        // Disable clipping for launches
+        // Modify the clipping for launching notifications
+        mLaunchAnimationParams = params;
         setLaunchingNotification(params != null);
+        updateLaunchedNotificationClipPath();
         requestChildrenUpdate();
     }
 
@@ -5353,7 +5415,15 @@
             return;
         }
         mLaunchingNotification = launching;
-        updateUseRoundedRectClipping();
+        mLaunchingNotificationNeedsToBeClipped = mLaunchAnimationParams != null
+                && (mLaunchAnimationParams.getStartRoundedTopClipping() > 0
+                        || mLaunchAnimationParams.getParentStartRoundedTopClipping() > 0);
+        if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification) {
+            mLaunchedNotificationClipPath.reset();
+        }
+        // When launching notifications, we're clipping the children individually instead of in
+        // dispatchDraw
+        invalidate();
     }
 
     /**
@@ -5363,22 +5433,97 @@
         // We don't want to clip notifications when QS is expanded, because incoming heads up on
         // the bottom would be clipped otherwise
         boolean qsAllowsClipping = mQsExpansionFraction < 0.5f || mShouldUseSplitNotificationShade;
-        boolean clip = !mLaunchingNotification && mIsExpanded && qsAllowsClipping;
+        boolean clip = mIsExpanded && qsAllowsClipping;
         if (clip != mShouldUseRoundedRectClipping) {
             mShouldUseRoundedRectClipping = clip;
             invalidate();
         }
     }
 
+    /**
+     * Update the clip path for launched notifications in case they were originally clipped
+     */
+    private void updateLaunchedNotificationClipPath() {
+        if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification
+                || mExpandingNotificationRow == null) {
+            return;
+        }
+        int left = Math.min(mLaunchAnimationParams.getLeft(), mRoundedRectClippingLeft);
+        int right = Math.max(mLaunchAnimationParams.getRight(), mRoundedRectClippingRight);
+        int bottom = Math.max(mLaunchAnimationParams.getBottom(), mRoundedRectClippingBottom);
+        float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
+                mLaunchAnimationParams.getProgress(0,
+                        NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
+        int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop,
+                mLaunchAnimationParams.getTop(), expandProgress),
+                mRoundedRectClippingTop);
+        float topRadius = mLaunchAnimationParams.getTopCornerRadius();
+        float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius();
+        mLaunchedNotificationRadii[0] = topRadius;
+        mLaunchedNotificationRadii[1] = topRadius;
+        mLaunchedNotificationRadii[2] = topRadius;
+        mLaunchedNotificationRadii[3] = topRadius;
+        mLaunchedNotificationRadii[4] = bottomRadius;
+        mLaunchedNotificationRadii[5] = bottomRadius;
+        mLaunchedNotificationRadii[6] = bottomRadius;
+        mLaunchedNotificationRadii[7] = bottomRadius;
+        mLaunchedNotificationClipPath.reset();
+        mLaunchedNotificationClipPath.addRoundRect(left, top, right, bottom,
+                mLaunchedNotificationRadii, Path.Direction.CW);
+        // Offset into notification clip coordinates instead of parent ones.
+        // This is needed since the notification changes in translationZ, where clipping via
+        // canvas dispatching won't work.
+        ExpandableNotificationRow expandingRow = mExpandingNotificationRow;
+        if (expandingRow.getNotificationParent() != null) {
+            expandingRow = expandingRow.getNotificationParent();
+        }
+        mLaunchedNotificationClipPath.offset(
+                -expandingRow.getLeft() - expandingRow.getTranslationX(),
+                -expandingRow.getTop() - expandingRow.getTranslationY());
+        expandingRow.setExpandingClipPath(mLaunchedNotificationClipPath);
+        if (mShouldUseRoundedRectClipping) {
+            invalidate();
+        }
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        if (mShouldUseRoundedRectClipping) {
+        if (mShouldUseRoundedRectClipping && !mLaunchingNotification) {
+            // When launching notifications, we're clipping the children individually instead of in
+            // dispatchDraw
             // Let's clip rounded.
             canvas.clipPath(mRoundedClipPath);
         }
         super.dispatchDraw(canvas);
     }
 
+    @Override
+    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        if (mShouldUseRoundedRectClipping && mLaunchingNotification) {
+            // Let's clip children individually during notification launch
+            canvas.save();
+            ExpandableView expandableView = (ExpandableView) child;
+            Path clipPath;
+            if (expandableView.isExpandAnimationRunning()
+                    || ((ExpandableView) child).hasExpandingChild()) {
+                // When launching the notification, it is not clipped by this layout, but by the
+                // view itself. This is because the view is Translating in Z, where this clipPath
+                // wouldn't apply.
+                clipPath = null;
+            } else {
+                clipPath = mRoundedClipPath;
+            }
+            if (clipPath != null) {
+                canvas.clipPath(clipPath);
+            }
+            boolean result = super.drawChild(canvas, child, drawingTime);
+            canvas.restore();
+            return result;
+        } else {
+            return super.drawChild(canvas, child, drawingTime);
+        }
+    }
+
     /**
      * Calculate the total translation needed when dismissing.
      */
@@ -5393,6 +5538,13 @@
     }
 
     /**
+     * @return the start location where we start clipping notifications.
+     */
+    public int getTopClippingStartLocation() {
+        return mIsExpanded ? mQsScrollBoundaryPosition : 0;
+    }
+
+    /**
      * A listener that is notified when the empty space below the notifications is clicked on
      */
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 495eda7..e71f7db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1533,6 +1533,11 @@
         }
 
         @Override
+        public int getTopClippingStartLocation() {
+            return mView.getTopClippingStartLocation();
+        }
+
+        @Override
         public View getContainerChildAt(int i) {
             return mView.getContainerChildAt(i);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
index 54ef623..b148eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
@@ -27,6 +27,7 @@
     private val listeners: MutableList<ConfigurationController.ConfigurationListener> = ArrayList()
     private val lastConfig = Configuration()
     private var density: Int = 0
+    private var smallestScreenWidth: Int = 0
     private var fontScale: Float = 0.toFloat()
     private val inCarMode: Boolean
     private var uiMode: Int = 0
@@ -38,6 +39,7 @@
         this.context = context
         fontScale = currentConfig.fontScale
         density = currentConfig.densityDpi
+        smallestScreenWidth = currentConfig.smallestScreenWidthDp
         inCarMode = currentConfig.uiMode and Configuration.UI_MODE_TYPE_MASK ==
                 Configuration.UI_MODE_TYPE_CAR
         uiMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
@@ -72,6 +74,14 @@
             this.fontScale = fontScale
         }
 
+        val smallestScreenWidth = newConfig.smallestScreenWidthDp
+        if (smallestScreenWidth != this.smallestScreenWidth) {
+            this.smallestScreenWidth = smallestScreenWidth
+            listeners.filterForEach({ this.listeners.contains(it) }) {
+                it.onSmallestScreenWidthChanged()
+            }
+        }
+
         val localeList = newConfig.locales
         if (localeList != this.localeList) {
             this.localeList = localeList
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index f461d94..5d31786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -36,9 +36,11 @@
 import android.app.ActivityManager;
 import android.app.Fragment;
 import android.app.StatusBarManager;
+import android.content.ContentResolver;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -50,10 +52,12 @@
 import android.graphics.drawable.Drawable;
 import android.hardware.biometrics.BiometricSourceType;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserManager;
 import android.os.VibrationEffect;
+import android.provider.Settings;
 import android.util.Log;
 import android.util.MathUtils;
 import android.view.LayoutInflater;
@@ -210,6 +214,8 @@
             new MyOnHeadsUpChangedListener();
     private final HeightListener mHeightListener = new HeightListener();
     private final ConfigurationListener mConfigurationListener = new ConfigurationListener();
+    private final SettingsChangeObserver mSettingsChangeObserver;
+
     @VisibleForTesting final StatusBarStateListener mStatusBarStateListener =
             new StatusBarStateListener();
     private final BiometricUnlockController mBiometricUnlockController;
@@ -594,6 +600,8 @@
     private int mScreenCornerRadius;
     private boolean mQSAnimatingHiddenFromCollapsed;
 
+    private final ContentResolver mContentResolver;
+
     private final Executor mUiExecutor;
     private final SecureSettings mSecureSettings;
 
@@ -635,6 +643,7 @@
     @Inject
     public NotificationPanelViewController(NotificationPanelView view,
             @Main Resources resources,
+            @Main Handler handler,
             LayoutInflater layoutInflater,
             NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler,
             DynamicPrivacyController dynamicPrivacyController,
@@ -678,6 +687,7 @@
             TapAgainViewController tapAgainViewController,
             NavigationModeController navigationModeController,
             FragmentService fragmentService,
+            ContentResolver contentResolver,
             QuickAccessWalletController quickAccessWalletController,
             @Main Executor uiExecutor,
             SecureSettings secureSettings,
@@ -704,15 +714,12 @@
         mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
         mDepthController = notificationShadeDepthController;
         mFeatureFlags = featureFlags;
+        mContentResolver = contentResolver;
         mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
         mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
         mQSDetailDisplayer = qsDetailDisplayer;
         mFragmentService = fragmentService;
-        mKeyguardUserSwitcherEnabled = mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher);
-        mKeyguardQsUserSwitchEnabled =
-                mKeyguardUserSwitcherEnabled && mResources.getBoolean(
-                        R.bool.config_keyguard_user_switch_opens_qs_details);
+        mSettingsChangeObserver = new SettingsChangeObserver(handler);
         mShouldUseSplitNotificationShade =
                 Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources);
         mView.setWillNotDraw(!DEBUG);
@@ -795,6 +802,7 @@
         }
 
         mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count);
+        updateUserSwitcherFlags();
         onFinishInflate();
     }
 
@@ -1034,6 +1042,10 @@
                 view = mLayoutInflater.inflate(layoutId, mView, false);
                 mView.addView(view, index);
             } else {
+                // Add the stub back so we can re-inflate it again if necessary
+                ViewStub stub = new ViewStub(mView.getContext(), layoutId);
+                stub.setId(stubId);
+                mView.addView(stub, index);
                 view = null;
             }
         } else if (enabled) {
@@ -1061,6 +1073,7 @@
         updateResources();
 
         // Re-inflate the keyguard user switcher group.
+        updateUserSwitcherFlags();
         boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled();
         boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled;
         boolean showKeyguardUserSwitcher =
@@ -1443,7 +1456,6 @@
 
     private void setQsExpansionEnabled() {
         mQsExpansionEnabled = mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient;
-        Log.d(TAG, "Set qsExpansionEnabled: " + mQsExpansionEnabled);
         if (mQs == null) return;
         mQs.setHeaderClickable(mQsExpansionEnabled);
     }
@@ -3874,6 +3886,26 @@
         return false;
     }
 
+    private void updateUserSwitcherFlags() {
+        mKeyguardUserSwitcherEnabled = mResources.getBoolean(
+                com.android.internal.R.bool.config_keyguardUserSwitcher);
+        mKeyguardQsUserSwitchEnabled =
+                mKeyguardUserSwitcherEnabled && mResources.getBoolean(
+                        R.bool.config_keyguard_user_switch_opens_qs_details);
+    }
+
+    private void registerSettingsChangeListener() {
+        mContentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED),
+                /* notifyForDescendants */ false,
+                mSettingsChangeObserver
+        );
+    }
+
+    private void unregisterSettingsChangeListener() {
+        mContentResolver.unregisterContentObserver(mSettingsChangeObserver);
+    }
+
     private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener {
         @Override
         public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
@@ -4195,6 +4227,15 @@
         }
 
         @Override
+        public void onSmallestScreenWidthChanged() {
+            if (DEBUG) Log.d(TAG, "onSmallestScreenWidthChanged");
+
+            // Can affect multi-user switcher visibility as it depends on screen size by default:
+            // it is enabled only for devices with large screens (see config_keyguardUserSwitcher)
+            reInflateViews();
+        }
+
+        @Override
         public void onOverlayChanged() {
             if (DEBUG) Log.d(TAG, "onOverlayChanged");
             reInflateViews();
@@ -4207,6 +4248,21 @@
         }
     }
 
+    private class SettingsChangeObserver extends ContentObserver {
+
+        SettingsChangeObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (DEBUG) Log.d(TAG, "onSettingsChanged");
+
+            // Can affect multi-user switcher visibility
+            reInflateViews();
+        }
+    }
+
     private class StatusBarStateListener implements StateListener {
         @Override
         public void onStateChanged(int statusBarState) {
@@ -4322,10 +4378,12 @@
             mConfigurationListener.onThemeChanged();
             mFalsingManager.addTapListener(mFalsingTapListener);
             mKeyguardIndicationController.init();
+            registerSettingsChangeListener();
         }
 
         @Override
         public void onViewDetachedFromWindow(View v) {
+            unregisterSettingsChangeListener();
             mFragmentService.getFragmentHostManager(mView)
                             .removeTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.removeCallback(mStatusBarStateListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 1cb0be0..ed8fb31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -47,6 +47,8 @@
     private View mKeyguardStatusBar;
     private boolean mQsExpanded;
     private boolean mCustomizerAnimating;
+    private boolean mCustomizing;
+    private boolean mDetailShowing;
 
     private int mBottomPadding;
     private int mStackScrollerMargin;
@@ -140,7 +142,18 @@
     }
 
     public void setCustomizerShowing(boolean isShowing) {
-        if (isShowing) {
+        mCustomizing = isShowing;
+        updateBottomMargin();
+        mStackScroller.setQsCustomizerShowing(isShowing);
+    }
+
+    public void setDetailShowing(boolean isShowing) {
+        mDetailShowing = isShowing;
+        updateBottomMargin();
+    }
+
+    private void updateBottomMargin() {
+        if (mCustomizing || mDetailShowing) {
             // Clear out bottom paddings/margins so the qs customization can be full height.
             setPadding(0, 0, 0, 0);
             setBottomMargin(mStackScroller, 0);
@@ -148,7 +161,6 @@
             setPadding(0, 0, 0, mBottomPadding);
             setBottomMargin(mStackScroller, mStackScrollerMargin);
         }
-        mStackScroller.setQsCustomizerShowing(isShowing);
     }
 
     private void setBottomMargin(View v, int bottomMargin) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 399c850..a0edc7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -74,11 +74,13 @@
         mBrightnessMirror.setVisibility(View.VISIBLE);
         mVisibilityCallback.accept(true);
         mNotificationPanel.setPanelAlpha(0, true /* animate */);
+        mDepthController.setBrightnessMirrorVisible(true);
     }
 
     public void hideMirror() {
         mVisibilityCallback.accept(false);
         mNotificationPanel.setPanelAlpha(255, true /* animate */);
+        mDepthController.setBrightnessMirrorVisible(false);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
index 0a6cf7b..c2bd87c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
@@ -33,6 +33,7 @@
     interface ConfigurationListener {
         default void onConfigChanged(Configuration newConfig) {}
         default void onDensityOrFontScaleChanged() {}
+        default void onSmallestScreenWidthChanged() {}
         default void onOverlayChanged() {}
         default void onUiModeChanged() {}
         default void onThemeChanged() {}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index ca1f55e..11ddbd0 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -241,7 +241,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             boolean newWorkProfile = Intent.ACTION_MANAGED_PROFILE_ADDED.equals(intent.getAction());
-            boolean userStarted = Intent.ACTION_USER_STARTED.equals(intent.getAction());
+            boolean userStarted = Intent.ACTION_USER_SWITCHED.equals(intent.getAction());
             boolean isManagedProfile = mUserManager.isManagedProfile(
                     intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
             if (userStarted || newWorkProfile) {
@@ -288,7 +288,7 @@
     public void start() {
         if (DEBUG) Log.d(TAG, "Start");
         final IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_STARTED);
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
         filter.addAction(Intent.ACTION_WALLPAPER_CHANGED);
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mMainExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
index c5e35a4..8b394bf 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
@@ -16,13 +16,18 @@
 
 package com.android.systemui.toast;
 
+import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+
 import android.animation.Animator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.Application;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -53,7 +58,7 @@
     final ToastPlugin.Toast mPluginToast;
 
     private final String mPackageName;
-    private final int mUserId;
+    @UserIdInt private final int mUserId;
     private final LayoutInflater mLayoutInflater;
 
     final int mDefaultX = 0;
@@ -74,7 +79,7 @@
     }
 
     SystemUIToast(LayoutInflater layoutInflater, Context context, CharSequence text,
-            ToastPlugin.Toast pluginToast, String packageName, int userId,
+            ToastPlugin.Toast pluginToast, String packageName, @UserIdInt int userId,
             int orientation) {
         mLayoutInflater = layoutInflater;
         mContext = context;
@@ -248,6 +253,15 @@
             return null;
         }
 
+        final Context userContext;
+        try {
+            userContext = context.createPackageContextAsUser("android",
+                0, new UserHandle(userId));
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Could not create user package context");
+            return null;
+        }
+
         final ApplicationsState appState =
                 ApplicationsState.getInstance((Application) context.getApplicationContext());
         if (!appState.isUserAdded(userId)) {
@@ -255,9 +269,11 @@
                     + "packageName=" + packageName);
             return null;
         }
+
+        final PackageManager packageManager = userContext.getPackageManager();
         final AppEntry appEntry = appState.getEntry(packageName, userId);
         if (appEntry == null || appEntry.info == null
-                || !ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(appEntry)) {
+                || !showApplicationIcon(appEntry.info, packageManager)) {
             return null;
         }
 
@@ -265,7 +281,20 @@
         UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
         IconFactory iconFactory = IconFactory.obtain(context);
         Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
-                appInfo.loadUnbadgedIcon(context.getPackageManager()), user, true).icon;
+                appInfo.loadUnbadgedIcon(packageManager), user, true).icon;
         return new BitmapDrawable(context.getResources(), iconBmp);
     }
+
+    private static boolean showApplicationIcon(ApplicationInfo appInfo,
+            PackageManager packageManager) {
+        if (hasFlag(appInfo.flags, FLAG_UPDATED_SYSTEM_APP)) {
+            return packageManager.getLaunchIntentForPackage(appInfo.packageName)
+                != null;
+        }
+        return !hasFlag(appInfo.flags, FLAG_SYSTEM);
+    }
+
+    private static boolean hasFlag(int flags, int flag) {
+        return (flags & flag) != 0;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java
new file mode 100644
index 0000000..2b7a332
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv;
+
+import android.app.Activity;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+
+import java.util.function.Consumer;
+
+/**
+ * Generic bottom sheet with up to two icons in the beginning and two buttons.
+ */
+public abstract class TvBottomSheetActivity extends Activity {
+
+    private static final String TAG = TvBottomSheetActivity.class.getSimpleName();
+    private Drawable mBackgroundWithBlur;
+    private Drawable mBackgroundWithoutBlur;
+
+    private final Consumer<Boolean> mBlurConsumer = this::onBlurChanged;
+
+    private void onBlurChanged(boolean enabled) {
+        Log.v(TAG, "blur enabled: " + enabled);
+        getWindow().setBackgroundDrawable(enabled ? mBackgroundWithBlur : mBackgroundWithoutBlur);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.tv_bottom_sheet);
+
+        overridePendingTransition(R.anim.tv_bottom_sheet_enter, 0);
+
+        mBackgroundWithBlur = getResources()
+                .getDrawable(R.drawable.bottom_sheet_background_with_blur);
+        mBackgroundWithoutBlur = getResources().getDrawable(R.drawable.bottom_sheet_background);
+
+        DisplayMetrics metrics = getResources().getDisplayMetrics();
+        int screenWidth = metrics.widthPixels;
+        int screenHeight = metrics.heightPixels;
+        int marginPx = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_margin);
+
+        WindowManager.LayoutParams windowParams = getWindow().getAttributes();
+        windowParams.width = screenWidth - marginPx * 2;
+        windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        windowParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+        windowParams.horizontalMargin = 0f;
+        windowParams.verticalMargin = (float) marginPx / screenHeight;
+        windowParams.format = PixelFormat.TRANSPARENT;
+        windowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+        windowParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+        windowParams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        getWindow().setAttributes(windowParams);
+        getWindow().setElevation(getWindow().getElevation() + 5);
+        getWindow().setBackgroundBlurRadius(getResources().getDimensionPixelSize(
+                R.dimen.bottom_sheet_background_blur_radius));
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        getWindowManager().addCrossWindowBlurEnabledListener(mBlurConsumer);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        getWindowManager().removeCrossWindowBlurEnabledListener(mBlurConsumer);
+        super.onDetachedFromWindow();
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        overridePendingTransition(0, R.anim.tv_bottom_sheet_exit);
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index ab4b1f1..e570598 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -128,7 +128,7 @@
     private final MediaSessions mMediaSessions;
     protected C mCallbacks = new C();
     private final State mState = new State();
-    protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
+    protected final MediaSessionsCallbacks mMediaSessionsCallbacksW;
     private final Optional<Vibrator> mVibrator;
     private final boolean mHasVibrator;
     private boolean mShowA11yStream;
@@ -179,6 +179,7 @@
         mWorkerLooper = theadFactory.buildLooperOnNewThread(
                 VolumeDialogControllerImpl.class.getSimpleName());
         mWorker = new W(mWorkerLooper);
+        mMediaSessionsCallbacksW = new MediaSessionsCallbacks(mContext);
         mMediaSessions = createMediaSessions(mContext, mWorkerLooper, mMediaSessionsCallbacksW);
         mAudio = audioManager;
         mNoMan = notificationManager;
@@ -1148,83 +1149,98 @@
         private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
 
         private int mNextStream = DYNAMIC_STREAM_START_INDEX;
+        private final boolean mShowRemoteSessions;
+
+        public MediaSessionsCallbacks(Context context) {
+            mShowRemoteSessions = context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_volumeShowRemoteSessions);
+        }
 
         @Override
         public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
-            addStream(token, "onRemoteUpdate");
+            if (mShowRemoteSessions) {
+                addStream(token, "onRemoteUpdate");
 
-            int stream = 0;
-            synchronized (mRemoteStreams) {
-                 stream = mRemoteStreams.get(token);
-            }
-            Slog.d(TAG, "onRemoteUpdate: stream: " + stream + " volume: " + pi.getCurrentVolume());
-            boolean changed = mState.states.indexOfKey(stream) < 0;
-            final StreamState ss = streamStateW(stream);
-            ss.dynamic = true;
-            ss.levelMin = 0;
-            ss.levelMax = pi.getMaxVolume();
-            if (ss.level != pi.getCurrentVolume()) {
-                ss.level = pi.getCurrentVolume();
-                changed = true;
-            }
-            if (!Objects.equals(ss.remoteLabel, name)) {
-                ss.name = -1;
-                ss.remoteLabel = name;
-                changed = true;
-            }
-            if (changed) {
-                Log.d(TAG, "onRemoteUpdate: " + name + ": " + ss.level + " of " + ss.levelMax);
-                mCallbacks.onStateChanged(mState);
+                int stream = 0;
+                synchronized (mRemoteStreams) {
+                    stream = mRemoteStreams.get(token);
+                }
+                Slog.d(TAG,
+                        "onRemoteUpdate: stream: " + stream + " volume: " + pi.getCurrentVolume());
+                boolean changed = mState.states.indexOfKey(stream) < 0;
+                final StreamState ss = streamStateW(stream);
+                ss.dynamic = true;
+                ss.levelMin = 0;
+                ss.levelMax = pi.getMaxVolume();
+                if (ss.level != pi.getCurrentVolume()) {
+                    ss.level = pi.getCurrentVolume();
+                    changed = true;
+                }
+                if (!Objects.equals(ss.remoteLabel, name)) {
+                    ss.name = -1;
+                    ss.remoteLabel = name;
+                    changed = true;
+                }
+                if (changed) {
+                    Log.d(TAG, "onRemoteUpdate: " + name + ": " + ss.level + " of " + ss.levelMax);
+                    mCallbacks.onStateChanged(mState);
+                }
             }
         }
 
         @Override
         public void onRemoteVolumeChanged(Token token, int flags) {
-            addStream(token, "onRemoteVolumeChanged");
-            int stream = 0;
-            synchronized (mRemoteStreams) {
-                stream = mRemoteStreams.get(token);
-            }
-            final boolean showUI = shouldShowUI(flags);
-            Slog.d(TAG, "onRemoteVolumeChanged: stream: " + stream + " showui? " + showUI);
-            boolean changed = updateActiveStreamW(stream);
-            if (showUI) {
-                changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC);
-            }
-            if (changed) {
-                Slog.d(TAG, "onRemoteChanged: updatingState");
-                mCallbacks.onStateChanged(mState);
-            }
-            if (showUI) {
-                mCallbacks.onShowRequested(Events.SHOW_REASON_REMOTE_VOLUME_CHANGED);
+            if (mShowRemoteSessions) {
+                addStream(token, "onRemoteVolumeChanged");
+                int stream = 0;
+                synchronized (mRemoteStreams) {
+                    stream = mRemoteStreams.get(token);
+                }
+                final boolean showUI = shouldShowUI(flags);
+                Slog.d(TAG, "onRemoteVolumeChanged: stream: " + stream + " showui? " + showUI);
+                boolean changed = updateActiveStreamW(stream);
+                if (showUI) {
+                    changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC);
+                }
+                if (changed) {
+                    Slog.d(TAG, "onRemoteChanged: updatingState");
+                    mCallbacks.onStateChanged(mState);
+                }
+                if (showUI) {
+                    mCallbacks.onShowRequested(Events.SHOW_REASON_REMOTE_VOLUME_CHANGED);
+                }
             }
         }
 
         @Override
         public void onRemoteRemoved(Token token) {
-            int stream = 0;
-            synchronized (mRemoteStreams) {
-                if (!mRemoteStreams.containsKey(token)) {
-                    Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
-                            + "aborting remote removed for token:" +  token.toString());
-                    return;
+            if (mShowRemoteSessions) {
+                int stream = 0;
+                synchronized (mRemoteStreams) {
+                    if (!mRemoteStreams.containsKey(token)) {
+                        Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
+                                + "aborting remote removed for token:" + token.toString());
+                        return;
+                    }
+                    stream = mRemoteStreams.get(token);
                 }
-                stream = mRemoteStreams.get(token);
+                mState.states.remove(stream);
+                if (mState.activeStream == stream) {
+                    updateActiveStreamW(-1);
+                }
+                mCallbacks.onStateChanged(mState);
             }
-            mState.states.remove(stream);
-            if (mState.activeStream == stream) {
-                updateActiveStreamW(-1);
-            }
-            mCallbacks.onStateChanged(mState);
         }
 
         public void setStreamVolume(int stream, int level) {
-            final Token t = findToken(stream);
-            if (t == null) {
-                Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
-                return;
+            if (mShowRemoteSessions) {
+                final Token t = findToken(stream);
+                if (t == null) {
+                    Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
+                    return;
+                }
+                mMediaSessions.setVolume(t, level);
             }
-            mMediaSessions.setVolume(t, level);
         }
 
         private Token findToken(int stream) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index 5b50e89..6237031 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -25,6 +25,8 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.content.Context;
+import android.content.ContextWrapper;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
@@ -39,6 +41,7 @@
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -58,6 +61,7 @@
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
+    private Context mContextWrapper;
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private AccessibilityFloatingMenuController mController;
     private AccessibilityButtonTargetsObserver mTargetsObserver;
@@ -66,6 +70,16 @@
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardCallbackCaptor;
     private KeyguardUpdateMonitorCallback mKeyguardCallback;
 
+    @Before
+    public void setUp() throws Exception {
+        mContextWrapper = new ContextWrapper(mContext) {
+            @Override
+            public Context createContextAsUser(UserHandle user, int flags) {
+                return getBaseContext();
+            }
+        };
+    }
+
     @Test
     public void initController_registerListeners() {
         mController = setUpController();
@@ -105,7 +119,7 @@
     public void onKeyguardVisibilityChanged_showing_destroyWidget() {
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
 
@@ -131,7 +145,7 @@
         final int fakeUserId = 1;
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
         captureKeyguardUpdateMonitorCallback();
 
         mKeyguardCallback.onUserSwitching(fakeUserId);
@@ -144,7 +158,7 @@
         final int fakeUserId = 1;
         enableAccessibilityFloatingMenuConfig();
         mController = setUpController();
-        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext);
+        mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
         mKeyguardCallback.onKeyguardVisibilityChanged(true);
@@ -172,7 +186,7 @@
 
     @Test
     public void onAccessibilityButtonModeChanged_floatingModeAndHasButtonTargets_showWidget() {
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
                 UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -184,7 +198,7 @@
 
     @Test
     public void onAccessibilityButtonModeChanged_floatingModeAndNoButtonTargets_destroyWidget() {
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT);
         mController = setUpController();
 
@@ -195,7 +209,7 @@
 
     @Test
     public void onAccessibilityButtonModeChanged_navBarModeAndHasButtonTargets_destroyWidget() {
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
                 UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -207,7 +221,7 @@
 
     @Test
     public void onAccessibilityButtonModeChanged_navBarModeAndNoButtonTargets_destroyWidget() {
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT);
         mController = setUpController();
 
@@ -218,7 +232,7 @@
 
     @Test
     public void onAccessibilityButtonTargetsChanged_floatingModeAndHasButtonTargets_showWidget() {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+        Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
                 UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -230,7 +244,7 @@
 
     @Test
     public void onAccessibilityButtonTargetsChanged_floatingModeAndNoButtonTargets_destroyWidget() {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+        Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
                 UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -242,7 +256,7 @@
 
     @Test
     public void onAccessibilityButtonTargetsChanged_navBarModeAndHasButtonTargets_destroyWidget() {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+        Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
                 ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -254,7 +268,7 @@
 
     @Test
     public void onAccessibilityButtonTargetsChanged_navBarModeAndNoButtonTargets_destroyWidget() {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+        Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
                 ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT);
         mController = setUpController();
@@ -269,15 +283,15 @@
         mModeObserver = spy(Dependency.get(AccessibilityButtonModeObserver.class));
         mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
 
-        return new AccessibilityFloatingMenuController(mContext, mTargetsObserver,
+        return new AccessibilityFloatingMenuController(mContextWrapper, mTargetsObserver,
                 mModeObserver, mKeyguardUpdateMonitor);
     }
 
     private void enableAccessibilityFloatingMenuConfig() {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+        Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU,
                 UserHandle.USER_CURRENT);
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS,
                 UserHandle.USER_CURRENT);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 41f9877..0c750a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -53,6 +53,7 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -117,6 +118,8 @@
     @Mock
     private AccessibilityManager mAccessibilityManager;
     @Mock
+    private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    @Mock
     private ScreenLifecycle mScreenLifecycle;
     @Mock
     private Vibrator mVibrator;
@@ -176,6 +179,7 @@
                 mFalsingManager,
                 mPowerManager,
                 mAccessibilityManager,
+                mLockscreenShadeTransitionController,
                 mScreenLifecycle,
                 mVibrator,
                 Optional.of(mHbmProvider));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index 5923de6..f62587c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -35,6 +35,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -65,6 +66,8 @@
     @Mock
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock
+    private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    @Mock
     private DumpManager mDumpManager;
     @Mock
     private DelayableExecutor mExecutor;
@@ -106,6 +109,7 @@
                 mExecutor,
                 mDumpManager,
                 mKeyguardViewMediator,
+                mLockscreenShadeTransitionController,
                 mUdfpsController);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 6e21642..2c68661 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -135,8 +135,6 @@
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
 
         assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
@@ -154,8 +152,6 @@
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
 
         assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
@@ -176,9 +172,25 @@
         assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
+    }
+
+    @Test
+    public void onBindViewHolder_bindConnectedDevice_withSelectableDevice_showAddIcon() {
+        when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(mMediaDevices);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
         assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
+    }
+
+    @Test
+    public void onBindViewHolder_bindConnectedDevice_withoutSelectableDevice_hideAddIcon() {
+        when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(new ArrayList<>());
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE);
     }
 
     @Test
@@ -245,8 +257,6 @@
         assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
     }
@@ -263,8 +273,6 @@
         assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 589ae2e..9bd07b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -155,6 +155,7 @@
 
     @Test
     public void refresh_notInDragging_verifyUpdateAdapter() {
+        when(mMediaOutputBaseAdapter.getCurrentActivePosition()).thenReturn(-1);
         when(mMediaOutputBaseAdapter.isDragging()).thenReturn(false);
         mMediaOutputBaseDialogImpl.refresh();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index da63b8a..4980f74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -52,6 +52,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -108,7 +109,8 @@
                         Dependency.get(Dependency.MAIN_HANDLER),
                         mock(UiEventLogger.class),
                         mock(NavigationBarOverlayController.class),
-                        mock(ConfigurationController.class)));
+                        mock(ConfigurationController.class),
+                        mock(UserTracker.class)));
         initializeNavigationBars();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 4ec45b4..b1afeec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -76,6 +76,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -276,7 +277,8 @@
                 mock(SystemActions.class),
                 mHandler,
                 mock(NavigationBarOverlayController.class),
-                mUiEventLogger));
+                mUiEventLogger,
+                mock(UserTracker.class)));
     }
 
     private void processAllMessages() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index 67505c4..75ae9cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -35,7 +35,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -541,7 +540,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         View result = views.apply(mContext, null);
 
-        assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(BLOCK_CONVERSATIONS)
@@ -551,7 +552,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesNotEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
@@ -560,7 +563,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
@@ -570,7 +575,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesNotEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_STARRED_CONTACTS)
@@ -580,7 +587,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_STARRED_CONTACTS)
@@ -590,7 +599,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesNotEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_CONTACTS)
@@ -600,7 +611,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesNotEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_CONTACTS)
@@ -610,7 +623,9 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesNotEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
 
         tileWithDndBlocking = PERSON_TILE.toBuilder()
                 .setNotificationPolicyState(SHOW_CONTACTS)
@@ -619,7 +634,11 @@
                 tileWithDndBlocking, mOptions).getViews();
         result = views.apply(mContext, null);
 
-        assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout);
+        assertResourcesEqual(
+                result.getSourceLayoutResId(),
+                R.layout.people_tile_with_suppression_detail_content_horizontal);
+        assertThat(result.<TextView>findViewById(R.id.text_content).getText().toString())
+                .isEqualTo(mContext.getString(R.string.paused_by_dnd));
     }
 
     @Test
@@ -1068,4 +1087,21 @@
         return new PeopleTileViewHelper(mContext, tile, 0, options,
                 new PeopleTileKey(tile.getId(), 0, tile.getPackageName()));
     }
+
+    private void assertResourcesEqual(int expected, int actual) {
+        assertThat(getResourceName(actual)).isEqualTo(getResourceName(expected));
+    }
+
+    private void assertResourcesNotEqual(int expected, int actual) {
+        assertThat(getResourceName(actual)).isNotEqualTo(getResourceName(expected));
+    }
+
+    private String getResourceName(int resId) {
+        Resources resources = mContext.getResources();
+        try {
+            return resources.getResourceEntryName(resId);
+        } catch (Resources.NotFoundException e) {
+            return String.valueOf(resId);
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java
index 9c68f0d..478658e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java
@@ -57,16 +57,19 @@
 
     private int mScrollDelta;
     private int mPageHeight;
+    private int mTargetHeight;
 
     FakeSession(int pageHeight, float maxPages, int tileHeight, int visiblePageTop,
-            int visiblePageBottom, int availableTop, int availableBottom) {
+            int visiblePageBottom, int availableTop, int availableBottom,
+            int maxTiles) {
         mPageHeight = pageHeight;
         mTileHeight = tileHeight;
         mAvailable = new Rect(0, availableTop, getPageWidth(), availableBottom);
         mAvailableTop = new Rect(mAvailable);
         mAvailableTop.inset(0, 0, 0, pageHeight);
         mVisiblePage = new Rect(0, visiblePageTop, getPageWidth(), visiblePageBottom);
-        mMaxTiles = (int) Math.ceil((pageHeight * maxPages) / mTileHeight);
+        mTargetHeight = (int) (pageHeight * maxPages);
+        mMaxTiles = maxTiles;
     }
 
     private static Image mockImage() {
@@ -158,6 +161,11 @@
     }
 
     @Override
+    public int getTargetHeight() {
+        return mTargetHeight;
+    }
+
+    @Override
     public int getTileHeight() {
         return mTileHeight;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java
index 2520af9..4c8a4b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java
@@ -42,21 +42,6 @@
 @RunWith(AndroidTestingRunner.class)
 public class FakeSessionTest extends SysuiTestCase {
     @Test
-    public void testMaxTiles() {
-        FakeSession session = new FakeSession(
-                /* pageHeight */ 100,
-                /* maxPages */ 2.25f,
-                /* tileHeight */ 10,
-                /* visiblePageTop */ 0,
-                /* visiblePageBottom */ 100,
-                /* availableTop */ -250,
-                /* availableBottom */ 250);
-
-        // (pageHeight * maxPages) / tileHeight
-        assertEquals("getMaxTiles()", 23, session.getMaxTiles());
-    }
-
-    @Test
     public void testNonEmptyResult_hasImage() {
         FakeSession session = new FakeSession(
                 /* pageHeight */ 100,
@@ -65,7 +50,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ 0,
-                /* availableBottom */ 100);
+                /* availableBottom */ 100,
+                /* max Tiles */ 30);
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0));
         assertNotNull("result.image", result.image);
         assertNotNull("result.image.getHardwareBuffer()", result.image.getHardwareBuffer());
@@ -80,7 +66,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ 0,
-                /* availableBottom */ 100);
+                /* availableBottom */ 100,
+                /* max Tiles */ 30);
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-100));
         assertNull("result.image", result.image);
     }
@@ -94,7 +81,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -250,
-                /* availableBottom */ 250);
+                /* availableBottom */ 250,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0));
         assertEquals("requested top", 0, result.requested.top);
@@ -113,7 +101,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -250,
-                /* availableBottom */ 250);
+                /* availableBottom */ 250,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(90));
         assertEquals("requested top", 90, result.requested.top);
@@ -132,7 +121,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -250,
-                /* availableBottom */ 250);
+                /* availableBottom */ 250,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-100));
         assertEquals("requested top", -100, result.requested.top);
@@ -151,7 +141,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -250,
-                /* availableBottom */ 250);
+                /* availableBottom */ 250,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(150));
         assertEquals("requested top", 150, result.requested.top);
@@ -170,7 +161,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -100,
-                /* availableBottom */ 100);
+                /* availableBottom */ 100,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-125));
         assertEquals("requested top", -125, result.requested.top);
@@ -189,7 +181,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -100,
-                /* availableBottom */ 100);
+                /* availableBottom */ 100,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(75));
         assertEquals("requested top", 75, result.requested.top);
@@ -211,7 +204,8 @@
                 /* visiblePageTop */ 25,  // <<--
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -150,
-                /* availableBottom */ 150);
+                /* availableBottom */ 150,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-150));
         assertEquals("requested top", -150, result.requested.top);
@@ -233,7 +227,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 75,
                 /* availableTop */ -150,
-                /* availableBottom */ 150);
+                /* availableBottom */ 150,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(50));
         assertEquals("requested top", 50, result.requested.top);
@@ -252,7 +247,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -100,
-                /* availableBottom */ 200);
+                /* availableBottom */ 200,
+                /* max Tiles */ 30);
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-150));
         assertTrue("captured rect is empty", result.captured.isEmpty());
     }
@@ -266,7 +262,8 @@
                 /* visiblePageTop */ 0,
                 /* visiblePageBottom */ 100,
                 /* availableTop */ -100,
-                /* availableBottom */ 200);
+                /* availableBottom */ 200,
+                /* max Tiles */ 30);
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(200));
         assertTrue("captured rect is empty", result.captured.isEmpty());
     }
@@ -280,7 +277,8 @@
                 /* visiblePageTop */ 60,  // <<---
                 /* visiblePageBottom */ 0,
                 /* availableTop */ -150,
-                /* availableBottom */ 150);
+                /* availableBottom */ 150,
+                /* max Tiles */ 30);
 
         ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0));
         assertEquals("requested top", 0, result.requested.top);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
index 5bab1bc..10c878a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java
@@ -92,14 +92,16 @@
         // Each tile is cropped to the visible page size, which is inset 5px from the TOP
         // requested    result
         //   0,   50       5,   50
-        // -45,    5     -40,    5   <-- clear previous /  top
-        //   5,   55       5,   55   (not cropped, target is positioned fully within visible range)
-        //  55,  105      55,  105
-        // 105,  155     105,  155
-        // 155,  205     155,  205   <-- bottom
+        // -45,    5     -40,    5
+        // -90,  -40     -85,  -40   <-- clear previous /  top
+        // -40,   10     -40,   10   (not cropped, target is positioned fully within visible range)
+        //  10,   60      10,   60
+        //  60,  110      60,  110
+        // 110,  160     110,  160
+        // 160,  210     160,  210   <-- bottom
 
-        assertEquals("top", -40, screenshot.getTop());
-        assertEquals("bottom", 205, screenshot.getBottom());
+        assertEquals("top", -85, screenshot.getTop());
+        assertEquals("bottom", 210, screenshot.getBottom());
     }
 
     @Test
@@ -119,13 +121,14 @@
         // requested      result
         //    0,   50        0,   50   // not cropped, positioned within visible range
         //  -50,    0      -50,    0   <-- clear previous/reverse
-        //    0,   50     -  0,   45   // target now positioned at page bottom, bottom cropped
+        //    0,   50        0,   45   // target now positioned at page bottom, bottom cropped
         //   45,   95,      45,   90
         //   90,  140,     140,  135
-        //  135,  185      185,  180   <-- bottom
+        //  135,  185      185,  180
+        //  180,  230      180,  225   <-- bottom
 
         assertEquals("top", -50, screenshot.getTop());
-        assertEquals("bottom", 180, screenshot.getBottom());
+        assertEquals("bottom", 225, screenshot.getBottom());
     }
 
     @Test
@@ -265,7 +268,8 @@
                 mLocalVisibleBottom = mPageHeight;
             }
             Session session = new FakeSession(mPageHeight, mMaxPages, mTileHeight,
-                    mLocalVisibleTop, mLocalVisibleBottom, mAvailableTop, mAvailableBottom);
+                    mLocalVisibleTop, mLocalVisibleBottom, mAvailableTop, mAvailableBottom,
+                    /* maxTiles */ 30);
             ScrollCaptureClient client = mock(ScrollCaptureClient.class);
             when(client.start(/* response */ any(), /* maxPages */ anyFloat()))
                     .thenReturn(immediateFuture(session));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
index 7c7d2dc..2b44d8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar
 
 import android.content.res.Resources
+import android.view.CrossWindowBlurListeners
 import android.view.SurfaceControl
 import android.view.ViewRootImpl
 import androidx.test.filters.SmallTest
@@ -37,11 +38,13 @@
     @Mock lateinit var resources: Resources
     @Mock lateinit var dumpManager: DumpManager
     @Mock lateinit var transaction: SurfaceControl.Transaction
+    @Mock lateinit var corssWindowBlurListeners: CrossWindowBlurListeners
     lateinit var blurUtils: BlurUtils
 
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        `when`(corssWindowBlurListeners.isCrossWindowBlurEnabled).thenReturn(true)
         blurUtils = TestableBlurUtils()
     }
 
@@ -71,7 +74,7 @@
         verify(transaction).apply()
     }
 
-    inner class TestableBlurUtils() : BlurUtils(resources, dumpManager) {
+    inner class TestableBlurUtils() : BlurUtils(resources, corssWindowBlurListeners, dumpManager) {
         override fun supportsBlursOnWindows(): Boolean {
             return true
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 61c3835..60b3889 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -47,6 +47,7 @@
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.doThrow
 import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
@@ -71,6 +72,7 @@
     @Mock private lateinit var shadeSpring: NotificationShadeDepthController.DepthAnimation
     @Mock private lateinit var shadeAnimation: NotificationShadeDepthController.DepthAnimation
     @Mock private lateinit var globalActionsSpring: NotificationShadeDepthController.DepthAnimation
+    @Mock private lateinit var brightnessSpring: NotificationShadeDepthController.DepthAnimation
     @Mock private lateinit var listener: NotificationShadeDepthController.DepthListener
     @Mock private lateinit var dozeParameters: DozeParameters
     @Captor private lateinit var scrimVisibilityCaptor: ArgumentCaptor<Consumer<Int>>
@@ -90,7 +92,11 @@
         `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer ->
             (answer.arguments[0] as Float * maxBlur).toInt()
         }
-        `when`(blurUtils.minBlurRadius).thenReturn(0)
+        `when`(blurUtils.ratioOfBlurRadius(anyInt())).then { answer ->
+            answer.arguments[0] as Int / maxBlur.toFloat()
+        }
+        `when`(blurUtils.supportsBlursOnWindows()).thenReturn(true)
+        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
         `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
 
         notificationShadeDepthController = NotificationShadeDepthController(
@@ -99,6 +105,7 @@
                 notificationShadeWindowController, dozeParameters, dumpManager)
         notificationShadeDepthController.shadeSpring = shadeSpring
         notificationShadeDepthController.shadeAnimation = shadeAnimation
+        notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring
         notificationShadeDepthController.globalActionsSpring = globalActionsSpring
         notificationShadeDepthController.root = root
 
@@ -191,6 +198,14 @@
     }
 
     @Test
+    fun setFullShadeTransition_appliesBlur_onlyIfSupported() {
+        reset(blurUtils)
+        notificationShadeDepthController.transitionToFullShadeProgress = 1f
+        notificationShadeDepthController.updateBlurCallback.doFrame(0)
+        verify(blurUtils).applyBlur(any(), eq(0), eq(false))
+    }
+
+    @Test
     fun updateGlobalDialogVisibility_animatesBlur() {
         notificationShadeDepthController.updateGlobalDialogVisibility(0.5f, root)
         verify(globalActionsSpring).animateTo(eq(maxBlur / 2), eq(root))
@@ -267,6 +282,32 @@
     }
 
     @Test
+    fun brightnessMirrorVisible_whenVisible() {
+        notificationShadeDepthController.brightnessMirrorVisible = true
+        verify(brightnessSpring).animateTo(eq(maxBlur), any())
+    }
+
+    @Test
+    fun brightnessMirrorVisible_whenHidden() {
+        notificationShadeDepthController.brightnessMirrorVisible = false
+        verify(brightnessSpring).animateTo(eq(0), any())
+    }
+
+    @Test
+    fun brightnessMirror_hidesShadeBlur() {
+        // Brightness mirror is fully visible
+        `when`(brightnessSpring.ratio).thenReturn(1f)
+        // And shade is blurred
+        `when`(shadeSpring.radius).thenReturn(maxBlur)
+        `when`(shadeAnimation.radius).thenReturn(maxBlur)
+
+        notificationShadeDepthController.updateBlurCallback.doFrame(0)
+        verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
+        verify(wallpaperManager).setWallpaperZoomOut(any(), eq(1f))
+        verify(blurUtils).applyBlur(eq(viewRootImpl), eq(0), eq(false))
+    }
+
+    @Test
     fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() {
         `when`(shadeSpring.radius).thenReturn(0)
         `when`(shadeAnimation.radius).thenReturn(0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 2d51683..2693b94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -26,9 +26,12 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -37,9 +40,13 @@
 
 import android.annotation.IdRes;
 import android.app.ActivityManager;
+import android.content.ContentResolver;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.hardware.biometrics.BiometricSourceType;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.os.UserManager;
 import android.testing.AndroidTestingRunner;
@@ -50,6 +57,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
+import android.view.ViewStub;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -60,6 +68,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardClockSwitchController;
@@ -140,6 +149,7 @@
     private KeyguardBottomAreaView mKeyguardBottomArea;
     @Mock
     private KeyguardBottomAreaView mQsFrame;
+    private KeyguardStatusView mKeyguardStatusView;
     @Mock
     private ViewGroup mBigClockContainer;
     @Mock
@@ -153,6 +163,10 @@
     @Mock
     private KeyguardStatusBarView mKeyguardStatusBar;
     @Mock
+    private View mUserSwitcherView;
+    @Mock
+    private ViewStub mUserSwitcherStubView;
+    @Mock
     private HeadsUpTouchHelper.Callback mHeadsUpCallback;
     @Mock
     private PanelBar mPanelBar;
@@ -204,7 +218,6 @@
     @Mock
     private KeyguardClockSwitch mKeyguardClockSwitch;
     private PanelViewController.TouchHandler mTouchHandler;
-    @Mock
     private ConfigurationController mConfigurationController;
     @Mock
     private MediaHierarchyManager mMediaHiearchyManager;
@@ -265,6 +278,8 @@
     @Mock
     private SecureSettings mSecureSettings;
     @Mock
+    private ContentResolver mContentResolver;
+    @Mock
     private TapAgainViewController mTapAgainViewController;
     @Mock
     private KeyguardIndicationController mKeyguardIndicationController;
@@ -287,6 +302,9 @@
         MockitoAnnotations.initMocks(this);
         mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger);
 
+        mKeyguardStatusView = new KeyguardStatusView(mContext);
+        mKeyguardStatusView.setId(R.id.keyguard_status_view);
+
         when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
         when(mHeadsUpCallback.getContext()).thenReturn(mContext);
         when(mView.getResources()).thenReturn(mResources);
@@ -301,6 +319,9 @@
         when(mResources.getDimensionPixelSize(R.dimen.notification_panel_width)).thenReturn(400);
         when(mView.getContext()).thenReturn(getContext());
         when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
+        when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView);
+        when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn(
+                mUserSwitcherStubView);
         when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
         when(mView.findViewById(R.id.notification_stack_scroller))
                 .thenReturn(mNotificationStackScrollLayout);
@@ -320,7 +341,7 @@
         mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
         mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame));
         mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller));
-        mNotificationContainerParent.addView(newViewWithId(R.id.keyguard_status_view));
+        mNotificationContainerParent.addView(mKeyguardStatusView);
         when(mView.findViewById(R.id.notification_container_parent))
                 .thenReturn(mNotificationContainerParent);
         when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager);
@@ -348,6 +369,7 @@
                 mFalsingManager,
                 mLockscreenShadeTransitionController,
                 new FalsingCollectorFake());
+        mConfigurationController = new ConfigurationControllerImpl(mContext);
         when(mKeyguardStatusViewComponentFactory.build(any()))
                 .thenReturn(mKeyguardStatusViewComponent);
         when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
@@ -358,10 +380,16 @@
                 .thenReturn(mKeyguardStatusBarViewComponent);
         when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
                 .thenReturn(mKeyguardStatusBarViewController);
+        when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
+                .thenReturn(mKeyguardStatusView);
+        when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
+                .thenReturn(mKeyguardBottomArea);
 
         reset(mView);
+
         mNotificationPanelViewController = new NotificationPanelViewController(mView,
                 mResources,
+                new Handler(Looper.getMainLooper()),
                 mLayoutInflater,
                 coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
                 mFalsingManager, new FalsingCollectorFake(),
@@ -395,6 +423,7 @@
                 mTapAgainViewController,
                 mNavigationModeController,
                 mFragmentService,
+                mContentResolver,
                 mQuickAccessWalletController,
                 new FakeExecutor(new FakeSystemClock()),
                 mSecureSettings,
@@ -549,6 +578,38 @@
     }
 
     @Test
+    public void testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() {
+        givenViewAttached();
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
+        updateMultiUserSetting(true);
+        clearInvocations(mView);
+
+        updateMultiUserSetting(false);
+
+        ArgumentCaptor<View> captor = ArgumentCaptor.forClass(View.class);
+        verify(mView, atLeastOnce()).addView(captor.capture(), anyInt());
+        final View userSwitcherStub = CollectionUtils.find(captor.getAllValues(),
+                view -> view.getId() == R.id.keyguard_user_switcher_stub);
+        assertThat(userSwitcherStub).isNotNull();
+        assertThat(userSwitcherStub).isInstanceOf(ViewStub.class);
+    }
+
+    @Test
+    public void testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() {
+        givenViewAttached();
+        when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(null);
+        updateSmallestScreenWidth(300);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
+        when(mUserManager.isUserSwitcherEnabled()).thenReturn(true);
+
+        updateSmallestScreenWidth(800);
+
+        verify(mUserSwitcherStubView).inflate();
+    }
+
+    @Test
     public void testSplitShadeLayout_isAlignedToGuideline() {
         enableSplitShade();
 
@@ -682,6 +743,12 @@
         return mFalsingManager.getTapListeners().get(0);
     }
 
+    private void givenViewAttached() {
+        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
+            listener.onViewAttachedToWindow(mView);
+        }
+    }
+
     private View newViewWithId(int id) {
         View view = new View(mContext);
         view.setId(id);
@@ -704,6 +771,21 @@
         mNotificationPanelViewController.updateResources();
     }
 
+    private void updateMultiUserSetting(boolean enabled) {
+        when(mUserManager.isUserSwitcherEnabled()).thenReturn(enabled);
+        final ArgumentCaptor<ContentObserver> observerCaptor =
+                ArgumentCaptor.forClass(ContentObserver.class);
+        verify(mContentResolver)
+                .registerContentObserver(any(), anyBoolean(), observerCaptor.capture());
+        observerCaptor.getValue().onChange(/* selfChange */ false);
+    }
+
+    private void updateSmallestScreenWidth(int smallestScreenWidthDp) {
+        Configuration configuration = new Configuration();
+        configuration.smallestScreenWidthDp = smallestScreenWidthDp;
+        mConfigurationController.onConfigurationChanged(configuration);
+    }
+
     private void onTouchEvent(MotionEvent ev) {
         mTouchHandler.onTouch(mView, ev);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 208790b..1a24c11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -415,13 +415,6 @@
     }
 
     @Test
-    public void onUserSwitch_setsTheme() {
-        mBroadcastReceiver.getValue().onReceive(null,
-                new Intent(Intent.ACTION_USER_STARTED));
-        verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
-    }
-
-    @Test
     public void onProfileAdded_setsTheme() {
         mBroadcastReceiver.getValue().onReceive(null,
                 new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED));
diff --git a/packages/services/CameraExtensionsProxy/AndroidManifest.xml b/packages/services/CameraExtensionsProxy/AndroidManifest.xml
index e5f460e..d356894 100644
--- a/packages/services/CameraExtensionsProxy/AndroidManifest.xml
+++ b/packages/services/CameraExtensionsProxy/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.camera">
+    package="com.android.cameraextensions">
 
     <application
         android:label="@string/app_name"
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/camera/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
similarity index 99%
rename from packages/services/CameraExtensionsProxy/src/com/android/camera/CameraExtensionsProxyService.java
rename to packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index 7b9ca2d..69874f8 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/camera/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.camera;
+package com.android.cameraextensions;
 
 import android.app.Service;
 import android.content.Context;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 241a0db..f631988 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -872,18 +872,32 @@
                     "userId=" + userId);
         }
 
+        final int resolvedUserId;
+        final List<AccessibilityServiceInfo> serviceInfos;
         synchronized (mLock) {
             // We treat calls from a profile as if made by its parent as profiles
             // share the accessibility state of the parent. The call below
             // performs the current profile parent resolution.
-            final int resolvedUserId = mSecurityPolicy
+            resolvedUserId = mSecurityPolicy
                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
-
-            if (Binder.getCallingPid() == OWN_PROCESS_ID) {
-                return new ArrayList<>(getUserStateLocked(resolvedUserId).mInstalledServices);
-            }
-            return getUserStateLocked(resolvedUserId).mInstalledServices;
+            serviceInfos = new ArrayList<>(
+                    getUserStateLocked(resolvedUserId).mInstalledServices);
         }
+
+        if (Binder.getCallingPid() == OWN_PROCESS_ID) {
+            return serviceInfos;
+        }
+        final PackageManagerInternal pm = LocalServices.getService(
+                PackageManagerInternal.class);
+        final int callingUid = Binder.getCallingUid();
+        for (int i = serviceInfos.size() - 1; i >= 0; i--) {
+            final AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
+            if (pm.filterAppAccess(serviceInfo.getComponentName().getPackageName(), callingUid,
+                    resolvedUserId)) {
+                serviceInfos.remove(i);
+            }
+        }
+        return serviceInfos;
     }
 
     @Override
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index acbf487..5aec6aa 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -409,6 +409,8 @@
 
                 // If the set of providers has been modified, notify each active AppWidgetHost
                 scheduleNotifyGroupHostsForProvidersChangedLocked(userId);
+                // Possibly notify any new components of widget id changes
+                mBackupRestoreController.widgetComponentsChanged(userId);
             }
         }
     }
@@ -2471,8 +2473,8 @@
     }
 
     @Override
-    public void restoreStarting(int userId) {
-        mBackupRestoreController.restoreStarting(userId);
+    public void systemRestoreStarting(int userId) {
+        mBackupRestoreController.systemRestoreStarting(userId);
     }
 
     @Override
@@ -2481,8 +2483,8 @@
     }
 
     @Override
-    public void restoreFinished(int userId) {
-        mBackupRestoreController.restoreFinished(userId);
+    public void systemRestoreFinished(int userId) {
+        mBackupRestoreController.systemRestoreFinished(userId);
     }
 
     @SuppressWarnings("deprecation")
@@ -4272,6 +4274,9 @@
         private final HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost =
                 new HashMap<>();
 
+        @GuardedBy("mLock")
+        private boolean mHasSystemRestoreFinished;
+
         public List<String> getWidgetParticipants(int userId) {
             if (DEBUG) {
                 Slog.i(TAG, "Getting widget participants for user: " + userId);
@@ -4375,12 +4380,13 @@
             return stream.toByteArray();
         }
 
-        public void restoreStarting(int userId) {
+        public void systemRestoreStarting(int userId) {
             if (DEBUG) {
-                Slog.i(TAG, "Restore starting for user: " + userId);
+                Slog.i(TAG, "System restore starting for user: " + userId);
             }
 
             synchronized (mLock) {
+                mHasSystemRestoreFinished = false;
                 // We're starting a new "system" restore operation, so any widget restore
                 // state that we see from here on is intended to replace the current
                 // widget configuration of any/all of the affected apps.
@@ -4542,26 +4548,90 @@
             }
         }
 
-        // Called once following the conclusion of a restore operation.  This is when we
+        // Called once following the conclusion of a system restore operation.  This is when we
         // send out updates to apps involved in widget-state restore telling them about
-        // the new widget ID space.
-        public void restoreFinished(int userId) {
+        // the new widget ID space.  Apps that are not yet installed will be notifed when they are.
+        public void systemRestoreFinished(int userId) {
             if (DEBUG) {
-                Slog.i(TAG, "restoreFinished for " + userId);
+                Slog.i(TAG, "systemRestoreFinished for " + userId);
+            }
+            synchronized (mLock) {
+                mHasSystemRestoreFinished = true;
+                maybeSendWidgetRestoreBroadcastsLocked(userId);
+            }
+        }
+
+        // Called when widget components (hosts or providers) are added or changed.  If system
+        // restore has completed, we use this opportunity to tell the apps to update to the new
+        // widget ID space.  If system restore is still in progress, we delay the updates until
+        // the end, to allow all participants to restore their state before updating widget IDs.
+        public void widgetComponentsChanged(int userId) {
+            synchronized (mLock) {
+                if (mHasSystemRestoreFinished) {
+                    maybeSendWidgetRestoreBroadcastsLocked(userId);
+                }
+            }
+        }
+
+        // Called following the conclusion of a restore operation and when widget components
+        // are added or changed.  This is when we send out updates to apps involved in widget-state
+        // restore telling them about the new widget ID space.
+        @GuardedBy("mLock")
+        private void maybeSendWidgetRestoreBroadcastsLocked(int userId) {
+            if (DEBUG) {
+                Slog.i(TAG, "maybeSendWidgetRestoreBroadcasts for " + userId);
             }
 
             final UserHandle userHandle = new UserHandle(userId);
-            synchronized (mLock) {
-                // Build the providers' broadcasts and send them off
-                Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
-                        = mUpdatesByProvider.entrySet();
-                for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
-                    // For each provider there's a list of affected IDs
-                    Provider provider = e.getKey();
+            // Build the providers' broadcasts and send them off
+            Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
+                    = mUpdatesByProvider.entrySet();
+            for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
+                // For each provider there's a list of affected IDs
+                Provider provider = e.getKey();
+                if (provider.zombie) {
+                    // Provider not installed, we can't send them broadcasts yet.
+                    // We'll be called again when the provider is installed.
+                    continue;
+                }
+                ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                final int pending = countPendingUpdates(updates);
+                if (DEBUG) {
+                    Slog.i(TAG, "Provider " + provider + " pending: " + pending);
+                }
+                if (pending > 0) {
+                    int[] oldIds = new int[pending];
+                    int[] newIds = new int[pending];
+                    final int N = updates.size();
+                    int nextPending = 0;
+                    for (int i = 0; i < N; i++) {
+                        RestoreUpdateRecord r = updates.get(i);
+                        if (!r.notified) {
+                            r.notified = true;
+                            oldIds[nextPending] = r.oldId;
+                            newIds[nextPending] = r.newId;
+                            nextPending++;
+                            if (DEBUG) {
+                                Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
+                            }
+                        }
+                    }
+                    sendWidgetRestoreBroadcastLocked(
+                            AppWidgetManager.ACTION_APPWIDGET_RESTORED,
+                            provider, null, oldIds, newIds, userHandle);
+                }
+            }
+
+            // same thing per host
+            Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
+                    = mUpdatesByHost.entrySet();
+            for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
+                Host host = e.getKey();
+                if (host.id.uid != UNKNOWN_UID) {
                     ArrayList<RestoreUpdateRecord> updates = e.getValue();
                     final int pending = countPendingUpdates(updates);
                     if (DEBUG) {
-                        Slog.i(TAG, "Provider " + provider + " pending: " + pending);
+                        Slog.i(TAG, "Host " + host + " pending: " + pending);
                     }
                     if (pending > 0) {
                         int[] oldIds = new int[pending];
@@ -4581,43 +4651,8 @@
                             }
                         }
                         sendWidgetRestoreBroadcastLocked(
-                                AppWidgetManager.ACTION_APPWIDGET_RESTORED,
-                                provider, null, oldIds, newIds, userHandle);
-                    }
-                }
-
-                // same thing per host
-                Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
-                        = mUpdatesByHost.entrySet();
-                for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
-                    Host host = e.getKey();
-                    if (host.id.uid != UNKNOWN_UID) {
-                        ArrayList<RestoreUpdateRecord> updates = e.getValue();
-                        final int pending = countPendingUpdates(updates);
-                        if (DEBUG) {
-                            Slog.i(TAG, "Host " + host + " pending: " + pending);
-                        }
-                        if (pending > 0) {
-                            int[] oldIds = new int[pending];
-                            int[] newIds = new int[pending];
-                            final int N = updates.size();
-                            int nextPending = 0;
-                            for (int i = 0; i < N; i++) {
-                                RestoreUpdateRecord r = updates.get(i);
-                                if (!r.notified) {
-                                    r.notified = true;
-                                    oldIds[nextPending] = r.oldId;
-                                    newIds[nextPending] = r.newId;
-                                    nextPending++;
-                                    if (DEBUG) {
-                                        Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
-                                    }
-                                }
-                            }
-                            sendWidgetRestoreBroadcastLocked(
-                                    AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED,
-                                    null, host, oldIds, newIds, userHandle);
-                        }
+                                AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED,
+                                null, host, oldIds, newIds, userHandle);
                     }
                 }
             }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 312cde6..de5f47d 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -662,6 +662,26 @@
         return false;
     }
 
+    /**
+     * Requests a count of saved passwords from the current service.
+     *
+     * @return {@code true} if the request succeeded
+     */
+    // Called by Shell command
+    boolean requestSavedPasswordCount(@UserIdInt int userId, @NonNull IResultReceiver receiver) {
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+            if (service != null) {
+                service.requestSavedPasswordCount(receiver);
+                return true;
+            } else if (sVerbose) {
+                Slog.v(TAG, "requestSavedPasswordCount(): no service for " + userId);
+            }
+        }
+        return false;
+    }
+
     private void setLoggingLevelsLocked(boolean debug, boolean verbose) {
         com.android.server.autofill.Helper.sDebug = debug;
         android.view.autofill.Helper.sDebug = debug;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index a80efc4..5f2d4e8 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -76,6 +76,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.os.IResultReceiver;
 import com.android.server.LocalServices;
 import com.android.server.autofill.AutofillManagerService.AutofillCompatState;
 import com.android.server.autofill.AutofillManagerService.DisabledInfoCache;
@@ -1181,6 +1182,15 @@
     }
 
     @GuardedBy("mLock")
+    void requestSavedPasswordCount(IResultReceiver receiver) {
+        RemoteFillService remoteService =
+                new RemoteFillService(
+                        getContext(), mInfo.getServiceInfo().getComponentName(), mUserId,
+                        /* callbacks= */ null, mMaster.isInstantServiceAllowed());
+        remoteService.onSavedPasswordCountRequest(receiver);
+    }
+
+    @GuardedBy("mLock")
     @Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() {
         if (mRemoteAugmentedAutofillService == null) {
             final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 68e6290..1eaa59a 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -17,6 +17,7 @@
 package com.android.server.autofill;
 
 import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES;
+import static android.service.autofill.AutofillService.EXTRA_RESULT;
 
 import static com.android.server.autofill.AutofillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
 
@@ -89,6 +90,9 @@
             pw.println("  get bind-instant-service-allowed");
             pw.println("    Gets whether binding to services provided by instant apps is allowed");
             pw.println("");
+            pw.println("  get saved-password-count");
+            pw.println("    Gets the number of saved passwords in the current service.");
+            pw.println("");
             pw.println("  set log_level [off | debug | verbose]");
             pw.println("    Sets the Autofill log level.");
             pw.println("");
@@ -145,6 +149,8 @@
                 return getBindInstantService(pw);
             case "default-augmented-service-enabled":
                 return getDefaultAugmentedServiceEnabled(pw);
+            case "saved-password-count":
+                return getSavedPasswordCount(pw);
             default:
                 pw.println("Invalid set: " + what);
                 return -1;
@@ -342,6 +348,25 @@
         return 0;
     }
 
+    private int getSavedPasswordCount(PrintWriter pw) {
+        final int userId = getNextIntArgRequired();
+        CountDownLatch latch = new CountDownLatch(1);
+        IResultReceiver resultReceiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                pw.println("resultCode=" + resultCode);
+                if (resultCode == 0 && resultData != null) {
+                    pw.println("value=" + resultData.getInt(EXTRA_RESULT));
+                }
+                latch.countDown();
+            }
+        };
+        if (mService.requestSavedPasswordCount(userId, resultReceiver)) {
+            waitForLatch(pw, latch);
+        }
+        return 0;
+    }
+
     private int requestDestroy(PrintWriter pw) {
         if (!isNextArgSessions(pw)) {
             return -1;
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index b0755ac..94872b0 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.infra.AbstractRemoteService;
 import com.android.internal.infra.ServiceConnector;
+import com.android.internal.os.IResultReceiver;
 
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
@@ -225,6 +226,10 @@
                 }));
     }
 
+    void onSavedPasswordCountRequest(IResultReceiver receiver) {
+        run(service -> service.onSavedPasswordCountRequest(receiver));
+    }
+
     public void destroy() {
         unbind();
     }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 261ebe6..f07bac8 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -381,7 +381,7 @@
 
         // If we're starting a full-system restore, set up to begin widget ID remapping
         if (mIsSystemRestore) {
-            AppWidgetBackupBridge.restoreStarting(mUserId);
+            AppWidgetBackupBridge.systemRestoreStarting(mUserId);
         }
 
         try {
@@ -1133,8 +1133,10 @@
                     restoreAgentTimeoutMillis);
         }
 
-        // Kick off any work that may be needed regarding app widget restores
-        AppWidgetBackupBridge.restoreFinished(mUserId);
+        if (mIsSystemRestore) {
+            // Kick off any work that may be needed regarding app widget restores
+            AppWidgetBackupBridge.systemRestoreFinished(mUserId);
+        }
 
         // If this was a full-system restore, record the ancestral
         // dataset information
diff --git a/services/companion/java/com/android/server/companion/OWNERS b/services/companion/java/com/android/server/companion/OWNERS
index da723b3..734d8b6 100644
--- a/services/companion/java/com/android/server/companion/OWNERS
+++ b/services/companion/java/com/android/server/companion/OWNERS
@@ -1 +1 @@
-eugenesusla@google.com
\ No newline at end of file
+include /core/java/android/companion/OWNERS
\ No newline at end of file
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 9299624..f7ddd29 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -1151,6 +1151,8 @@
 
     /**
      * Deletes the OAT artifacts of a package.
+     * @param packageName a specific package
+     * @return the number of freed bytes or -1 if there was an error in the process.
      */
-    public abstract void deleteOatArtifactsOfPackage(String packageName);
+    public abstract long deleteOatArtifactsOfPackage(String packageName);
 }
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 26ecee8..70176a0 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -38,6 +38,7 @@
 import android.net.VpnService;
 import android.net.util.NetdService;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.INetworkManagementService;
@@ -348,9 +349,17 @@
     /**
      * Start legacy VPN, controlling native daemons as needed. Creates a
      * secondary thread to perform connection work, returning quickly.
+     *
+     * Legacy VPN is deprecated starting from Android S. So this API shouldn't be called if the
+     * initial SDK version of device is Android S+. Otherwise, UnsupportedOperationException will be
+     * thrown.
      */
+    @SuppressWarnings("AndroidFrameworkCompatChange")  // This is not an app-visible API.
     @Override
     public void startLegacyVpn(VpnProfile profile) {
+        if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.S) {
+            throw new UnsupportedOperationException("Legacy VPN is deprecated");
+        }
         int user = UserHandle.getUserId(mDeps.getCallingUid());
         // Note that if the caller is not system (uid >= Process.FIRST_APPLICATION_UID),
         // the code might not work well since getActiveNetwork might return null if the uid is
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5e388d9..3b3febe 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -6165,8 +6165,10 @@
                 && code != REASON_UID_VISIBLE;
     }
 
-    // TODO: remove this notification after feature development is done
     private void showFgsBgRestrictedNotificationLocked(ServiceRecord r) {
+        if (!mAm.mConstants.mFgsStartRestrictionNotificationEnabled /* default is false */) {
+            return;
+        }
         final Context context = mAm.mContext;
         final String title = "Foreground Service BG-Launch Restricted";
         final String content = "App restricted: " + r.mRecentCallingPackage;
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 0d19efc..445d0ba 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -198,6 +198,13 @@
             "default_fgs_starts_restriction_enabled";
 
     /**
+     * Default value for mFgsStartRestrictionNotificationEnabled if not explicitly set in
+     * Settings.Global.
+     */
+    private static final String KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED =
+            "default_fgs_starts_restriction_notification_enabled";
+
+    /**
      * Default value for mFgsStartRestrictionCheckCallerTargetSdk if not explicitly set in
      * Settings.Global.
      */
@@ -432,6 +439,10 @@
     // at all.
     volatile boolean mFlagFgsStartRestrictionEnabled = true;
 
+    // Whether to display a notification when a service is restricted from startForeground due to
+    // foreground service background start restriction.
+    volatile boolean mFgsStartRestrictionNotificationEnabled = false;
+
     /**
      * Indicates whether the foreground service background start restriction is enabled for
      * caller app that is targeting S+.
@@ -652,6 +663,9 @@
                             case KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED:
                                 updateFgsStartsRestriction();
                                 break;
+                            case KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED:
+                                updateFgsStartsRestrictionNotification();
+                                break;
                             case KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK:
                                 updateFgsStartsRestrictionCheckCallerTargetSdk();
                                 break;
@@ -953,6 +967,13 @@
                 /*defaultValue*/ true);
     }
 
+    private void updateFgsStartsRestrictionNotification() {
+        mFgsStartRestrictionNotificationEnabled = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED,
+                /*defaultValue*/ false);
+    }
+
     private void updateFgsStartsRestrictionCheckCallerTargetSdk() {
         mFgsStartRestrictionCheckCallerTargetSdk = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1272,6 +1293,9 @@
         pw.print("="); pw.println(mFlagBackgroundFgsStartRestrictionEnabled);
         pw.print("  "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED); pw.print("=");
         pw.println(mFlagFgsStartRestrictionEnabled);
+        pw.print("  "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED);
+                pw.print("=");
+        pw.println(mFgsStartRestrictionNotificationEnabled);
         pw.print("  "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK);
         pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk);
         pw.print("  "); pw.print(KEY_FGS_ATOM_SAMPLE_RATE);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2de091b..0c97724 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5684,6 +5684,16 @@
         if (pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
         }
+        try {
+            if (uid != 0) { // bypass the root
+                final String[] packageNames = getPackageManager().getPackagesForUid(uid);
+                if (ArrayUtils.isEmpty(packageNames)) {
+                    // The uid is not existed or not visible to the caller.
+                    return PackageManager.PERMISSION_DENIED;
+                }
+            }
+        } catch (RemoteException e) {
+        }
         return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags)
                 ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
     }
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 966e746..317b775 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -203,8 +203,6 @@
                                 updateMinOomAdjThrottle();
                             } else if (KEY_COMPACT_THROTTLE_MAX_OOM_ADJ.equals(name)) {
                                 updateMaxOomAdjThrottle();
-                            } else if (KEY_FREEZER_DEBOUNCE_TIMEOUT.equals(name)) {
-                                updateFreezerDebounceTimeout();
                             }
                         }
                     }
@@ -344,7 +342,6 @@
             updateUseFreezer();
             updateMinOomAdjThrottle();
             updateMaxOomAdjThrottle();
-            updateFreezerDebounceTimeout();
         }
     }
 
@@ -656,6 +653,7 @@
                 || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
                     KEY_USE_FREEZER, DEFAULT_USE_FREEZER)) {
             mUseFreezer = isFreezerSupported();
+            updateFreezerDebounceTimeout();
         }
 
         final boolean useFreezer = mUseFreezer;
@@ -834,7 +832,8 @@
 
     @GuardedBy("mPhenotypeFlagLock")
     private void updateFreezerDebounceTimeout() {
-        mFreezerDebounceTimeout = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+        mFreezerDebounceTimeout = DeviceConfig.getLong(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
                 KEY_FREEZER_DEBOUNCE_TIMEOUT, DEFAULT_FREEZER_DEBOUNCE_TIMEOUT);
 
         if (mFreezerDebounceTimeout < 0) {
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 697f6fa..ae1cd51 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -21,10 +21,18 @@
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 
 import static com.android.server.wm.CompatModePackages.DOWNSCALED;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_30;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_35;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_40;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_45;
 import static com.android.server.wm.CompatModePackages.DOWNSCALE_50;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_55;
 import static com.android.server.wm.CompatModePackages.DOWNSCALE_60;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_65;
 import static com.android.server.wm.CompatModePackages.DOWNSCALE_70;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_75;
 import static com.android.server.wm.CompatModePackages.DOWNSCALE_80;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_85;
 import static com.android.server.wm.CompatModePackages.DOWNSCALE_90;
 
 import android.Manifest;
@@ -213,6 +221,39 @@
         }
     }
 
+    // Turn the raw string to the corresponding CompatChange id.
+    static long getCompatChangeId(String raw) {
+        switch (raw) {
+            case "0.3":
+                return DOWNSCALE_30;
+            case "0.35":
+                return DOWNSCALE_35;
+            case "0.4":
+                return DOWNSCALE_40;
+            case "0.45":
+                return DOWNSCALE_45;
+            case "0.5":
+                return DOWNSCALE_50;
+            case "0.55":
+                return DOWNSCALE_55;
+            case "0.6":
+                return DOWNSCALE_60;
+            case "0.65":
+                return DOWNSCALE_65;
+            case "0.7":
+                return DOWNSCALE_70;
+            case "0.75":
+                return DOWNSCALE_75;
+            case "0.8":
+                return DOWNSCALE_80;
+            case "0.85":
+                return DOWNSCALE_85;
+            case "0.9":
+                return DOWNSCALE_90;
+        }
+        return 0;
+    }
+
     /**
      * GamePackageConfiguration manages all game mode config details for its associated package.
      */
@@ -331,19 +372,7 @@
              * Get the corresponding compat change id for the current scaling string.
              */
             public long getCompatChangeId() {
-                switch (mScaling) {
-                    case "0.5":
-                        return DOWNSCALE_50;
-                    case "0.6":
-                        return DOWNSCALE_60;
-                    case "0.7":
-                        return DOWNSCALE_70;
-                    case "0.8":
-                        return DOWNSCALE_80;
-                    case "0.9":
-                        return DOWNSCALE_90;
-                }
-                return 0;
+                return GameManagerService.getCompatChangeId(mScaling);
             }
         }
 
@@ -663,10 +692,18 @@
             Slog.i(TAG, "Enabling downscale: " + scaleId + " for " + packageName);
             final ArrayMap<Long, PackageOverride> overrides = new ArrayMap<>();
             overrides.put(DOWNSCALED, COMPAT_ENABLED);
+            overrides.put(DOWNSCALE_30, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_35, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_40, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_45, COMPAT_DISABLED);
             overrides.put(DOWNSCALE_50, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_55, COMPAT_DISABLED);
             overrides.put(DOWNSCALE_60, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_65, COMPAT_DISABLED);
             overrides.put(DOWNSCALE_70, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_75, COMPAT_DISABLED);
             overrides.put(DOWNSCALE_80, COMPAT_DISABLED);
+            overrides.put(DOWNSCALE_85, COMPAT_DISABLED);
             overrides.put(DOWNSCALE_90, COMPAT_DISABLED);
             overrides.put(scaleId, COMPAT_ENABLED);
             final CompatibilityOverrideConfig changeConfig = new CompatibilityOverrideConfig(
diff --git a/services/core/java/com/android/server/app/GameManagerShellCommand.java b/services/core/java/com/android/server/app/GameManagerShellCommand.java
index 2074ffa..699f9e2 100644
--- a/services/core/java/com/android/server/app/GameManagerShellCommand.java
+++ b/services/core/java/com/android/server/app/GameManagerShellCommand.java
@@ -16,6 +16,21 @@
 
 package com.android.server.app;
 
+import static com.android.server.wm.CompatModePackages.DOWNSCALED;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_30;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_35;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_40;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_45;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_50;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_55;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_60;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_65;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_70;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_75;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_80;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_85;
+import static com.android.server.wm.CompatModePackages.DOWNSCALE_90;
+
 import android.app.ActivityManager;
 import android.app.GameManager;
 import android.app.IGameManagerService;
@@ -27,7 +42,6 @@
 
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.server.compat.PlatformCompat;
-import com.android.server.wm.CompatModePackages;
 
 import java.io.PrintWriter;
 import java.util.Set;
@@ -43,12 +57,21 @@
     public GameManagerShellCommand() {}
 
     private static final ArraySet<Long> DOWNSCALE_CHANGE_IDS = new ArraySet<>(new Long[]{
-            CompatModePackages.DOWNSCALED,
-            CompatModePackages.DOWNSCALE_90,
-            CompatModePackages.DOWNSCALE_80,
-            CompatModePackages.DOWNSCALE_70,
-            CompatModePackages.DOWNSCALE_60,
-            CompatModePackages.DOWNSCALE_50});
+            DOWNSCALED,
+            DOWNSCALE_90,
+            DOWNSCALE_85,
+            DOWNSCALE_80,
+            DOWNSCALE_75,
+            DOWNSCALE_70,
+            DOWNSCALE_65,
+            DOWNSCALE_60,
+            DOWNSCALE_55,
+            DOWNSCALE_50,
+            DOWNSCALE_45,
+            DOWNSCALE_40,
+            DOWNSCALE_35,
+            DOWNSCALE_30,
+    });
 
     @Override
     public int onCommand(String cmd) {
@@ -62,32 +85,9 @@
                     final String ratio = getNextArgRequired();
                     final String packageName = getNextArgRequired();
 
-                    final long changeId;
-                    switch (ratio) {
-                        case "0.5":
-                            changeId = CompatModePackages.DOWNSCALE_50;
-                            break;
-                        case "0.6":
-                            changeId = CompatModePackages.DOWNSCALE_60;
-                            break;
-                        case "0.7":
-                            changeId = CompatModePackages.DOWNSCALE_70;
-                            break;
-                        case "0.8":
-                            changeId = CompatModePackages.DOWNSCALE_80;
-                            break;
-                        case "0.9":
-                            changeId = CompatModePackages.DOWNSCALE_90;
-                            break;
-                        case "disable":
-                            changeId = 0;
-                            break;
-                        default:
-                            changeId = -1;
-                            pw.println("Invalid scaling ratio '" + ratio + "'");
-                            break;
-                    }
-                    if (changeId == -1) {
+                    final long changeId = GameManagerService.getCompatChangeId(ratio);
+                    if (changeId == 0 && !ratio.equals("disable")) {
+                        pw.println("Invalid scaling ratio '" + ratio + "'");
                         break;
                     }
 
@@ -96,10 +96,10 @@
                     if (changeId == 0) {
                         disabled = DOWNSCALE_CHANGE_IDS;
                     } else {
-                        enabled.add(CompatModePackages.DOWNSCALED);
+                        enabled.add(DOWNSCALED);
                         enabled.add(changeId);
                         disabled = DOWNSCALE_CHANGE_IDS.stream()
-                          .filter(it -> it != CompatModePackages.DOWNSCALED && it != changeId)
+                          .filter(it -> it != DOWNSCALED && it != changeId)
                           .collect(Collectors.toSet());
                     }
 
@@ -204,7 +204,7 @@
         pw.println("Game manager (game) commands:");
         pw.println("  help");
         pw.println("      Print this help text.");
-        pw.println("  downscale [0.5|0.6|0.7|0.8|0.9|disable] <PACKAGE_NAME>");
+        pw.println("  downscale [0.3|0.35|0.4|0.45|0.5|0.55|0.6|0.65|0.7|0.75|0.8|0.85|0.9|disable] <PACKAGE_NAME>");
         pw.println("      Force app to run at the specified scaling ratio.");
         pw.println("  mode [--user <USER_ID>] [1|2|3|standard|performance|battery] <PACKAGE_NAME>");
         pw.println("      Force app to run in the specified game mode, if supported.");
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 4cb2e9b..7f1402d 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -456,7 +456,9 @@
     private void hibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) {
         Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "hibernatePackageGlobally");
         if (mOatArtifactDeletionEnabled) {
-            mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName);
+            state.savedByte = Math.max(
+                    mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName),
+                    0);
         }
         state.hibernated = true;
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
@@ -469,6 +471,7 @@
     private void unhibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) {
         Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "unhibernatePackageGlobally");
         state.hibernated = false;
+        state.savedByte = 0;
         state.lastUnhibernatedMs = System.currentTimeMillis();
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
     }
@@ -943,6 +946,9 @@
     }
 
     private final class StatsPullAtomCallbackImpl implements StatsPullAtomCallback {
+
+        private static final int MEGABYTE_IN_BYTES = 1000000;
+
         @Override
         public int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
             if (!isAppHibernationEnabled()
@@ -969,12 +975,21 @@
                     break;
                 case FrameworkStatsLog.GLOBAL_HIBERNATED_APPS:
                     int hibernatedAppCount = 0;
+                    long storage_saved_byte = 0;
                     synchronized (mLock) {
                         for (GlobalLevelState state : mGlobalHibernationStates.values()) {
-                            if (state.hibernated) hibernatedAppCount++;
+                            if (state.hibernated) {
+                                hibernatedAppCount++;
+                                storage_saved_byte += state.savedByte;
+                            }
                         }
                     }
-                    data.add(FrameworkStatsLog.buildStatsEvent(atomTag, hibernatedAppCount));
+                    data.add(
+                            FrameworkStatsLog.buildStatsEvent(
+                                    atomTag,
+                                    hibernatedAppCount,
+                                    storage_saved_byte / MEGABYTE_IN_BYTES)
+                    );
                     break;
                 default:
                     return StatsManager.PULL_SKIP;
diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java b/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java
index 79e995b..018d602 100644
--- a/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java
+++ b/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java
@@ -41,6 +41,7 @@
             GlobalLevelState state = data.get(i);
             stream.write(GlobalLevelHibernationStateProto.PACKAGE_NAME, state.packageName);
             stream.write(GlobalLevelHibernationStateProto.HIBERNATED, state.hibernated);
+            stream.write(GlobalLevelHibernationStateProto.SAVED_BYTE, state.savedByte);
             stream.end(token);
         }
     }
@@ -66,6 +67,10 @@
                         state.hibernated =
                                 stream.readBoolean(GlobalLevelHibernationStateProto.HIBERNATED);
                         break;
+                    case (int) GlobalLevelHibernationStateProto.SAVED_BYTE:
+                        state.savedByte =
+                                stream.readLong(GlobalLevelHibernationStateProto.SAVED_BYTE);
+                        break;
                     default:
                         Slog.w(TAG, "Undefined field in proto: " + stream.getFieldNumber());
                 }
diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
index f4433a7..104ecbc 100644
--- a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
+++ b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
@@ -29,6 +29,8 @@
 
     public String packageName;
     public boolean hibernated;
+    // The number of saved bytes from the current hibernation. It will be 0 if not in hibernation.
+    public long savedByte;
     @CurrentTimeMillisLong
     public long lastUnhibernatedMs;
 
@@ -37,6 +39,7 @@
         return "GlobalLevelState{"
                 + "packageName='" + packageName + '\''
                 + ", hibernated=" + hibernated + '\''
+                + ", savedByte=" + savedByte + '\''
                 + ", lastUnhibernated=" + DATE_FORMAT.format(lastUnhibernatedMs)
                 + '}';
     }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 99a33e4..5ba75d3 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -19,11 +19,13 @@
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
 import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP;
 import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
 import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
 import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
 import static android.app.AppOpsManager.FILTER_BY_UID;
+import static android.app.AppOpsManager.HISTORY_FLAG_GET_ATTRIBUTION_CHAINS;
 import static android.app.AppOpsManager.HistoricalOpsRequestFilter;
 import static android.app.AppOpsManager.KEY_BG_STATE_SETTLE_TIME;
 import static android.app.AppOpsManager.KEY_FG_SERVICE_STATE_SETTLE_TIME;
@@ -130,6 +132,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManagerInternal;
+import android.permission.PermissionManager;
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -200,8 +203,8 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Scanner;
+import java.util.Set;
 import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
 public class AppOpsService extends IAppOpsService.Stub {
@@ -2357,10 +2360,21 @@
         final String[] opNamesArray = (opNames != null)
                 ? opNames.toArray(new String[opNames.size()]) : null;
 
+        Set<String> attributionChainExemptPackages = null;
+        if ((dataType & HISTORY_FLAG_GET_ATTRIBUTION_CHAINS) != 0) {
+            attributionChainExemptPackages =
+                    PermissionManager.getIndicatorExemptedPackages(mContext);
+        }
+
+        final String[] chainExemptPkgArray = attributionChainExemptPackages != null
+                ? attributionChainExemptPackages.toArray(
+                        new String[attributionChainExemptPackages.size()]) : null;
+
         // Must not hold the appops lock
         mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::getHistoricalOps,
                 mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
-                filter, beginTimeMillis, endTimeMillis, flags, callback).recycleOnUse());
+                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
+                callback).recycleOnUse());
     }
 
     @Override
@@ -2377,10 +2391,21 @@
         final String[] opNamesArray = (opNames != null)
                 ? opNames.toArray(new String[opNames.size()]) : null;
 
+        Set<String> attributionChainExemptPackages = null;
+        if ((dataType & HISTORY_FLAG_GET_ATTRIBUTION_CHAINS) != 0) {
+            attributionChainExemptPackages =
+                    PermissionManager.getIndicatorExemptedPackages(mContext);
+        }
+
+        final String[] chainExemptPkgArray = attributionChainExemptPackages != null
+                ? attributionChainExemptPackages.toArray(
+                new String[attributionChainExemptPackages.size()]) : null;
+
         // Must not hold the appops lock
         mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::getHistoricalOpsFromDiskRaw,
                 mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType,
-                filter, beginTimeMillis, endTimeMillis, flags, callback).recycleOnUse());
+                filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray,
+                callback).recycleOnUse());
     }
 
     @Override
@@ -3838,7 +3863,8 @@
         final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid;
         final boolean isProxyTrusted = mContext.checkPermission(
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
-                == PackageManager.PERMISSION_GRANTED || isSelfBlame;
+                == PackageManager.PERMISSION_GRANTED || isSelfBlame
+                || attributionChainId != ATTRIBUTION_CHAIN_ID_NONE;
 
         String resolvedProxiedPackageName = AppOpsManager.resolvePackageName(proxiedUid,
                 proxiedPackageName);
@@ -5174,8 +5200,6 @@
     }
 
     static class Shell extends ShellCommand {
-        static final AtomicInteger sAttributionChainIds = new AtomicInteger(0);
-
         final IAppOpsService mInterface;
         final AppOpsService mInternal;
 
@@ -5645,8 +5669,7 @@
                         shell.mInterface.startOperation(shell.mToken, shell.op, shell.packageUid,
                                 shell.packageName, shell.attributionTag, true, true,
                                 "appops start shell command", true,
-                                AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR,
-                                shell.sAttributionChainIds.incrementAndGet());
+                                AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR, ATTRIBUTION_CHAIN_ID_NONE);
                     } else {
                         return -1;
                     }
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 49469cc..0439660 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -16,6 +16,9 @@
 
 package com.android.server.appop;
 
+import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
+import static android.app.AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR;
+import static android.app.AppOpsManager.ATTRIBUTION_FLAG_RECEIVER;
 import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
 import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
 import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
@@ -58,7 +61,9 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.time.Duration;
@@ -69,6 +74,8 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 
 /**
  * This class manages information about recent accesses to ops for permission usage timeline.
@@ -138,6 +145,7 @@
 
     private static final String TAG_HISTORY = "h";
     private static final String ATTR_VERSION = "v";
+    private static final String ATTR_LARGEST_CHAIN_ID = "lc";
     private static final int CURRENT_VERSION = 1;
 
     private static final String TAG_UID = "u";
@@ -182,6 +190,16 @@
 
     DiscreteRegistry(Object inMemoryLock) {
         mInMemoryLock = inMemoryLock;
+        synchronized (mOnDiskLock) {
+            mDiscreteAccessDir = new File(
+                    new File(Environment.getDataSystemDirectory(), "appops"),
+                    "discrete");
+            createDiscreteAccessDirLocked();
+            int largestChainId = readLargestChainIdFromDiskLocked();
+            synchronized (mInMemoryLock) {
+                mDiscreteOps = new DiscreteOps(largestChainId);
+            }
+        }
     }
 
     void systemReady() {
@@ -190,15 +208,6 @@
                     setDiscreteHistoryParameters(p);
                 });
         setDiscreteHistoryParameters(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_PRIVACY));
-        synchronized (mOnDiskLock) {
-            synchronized (mInMemoryLock) {
-                mDiscreteAccessDir = new File(
-                        new File(Environment.getDataSystemDirectory(), "appops"),
-                        "discrete");
-                createDiscreteAccessDirLocked();
-                mDiscreteOps = new DiscreteOps();
-            }
-        }
     }
 
     private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
@@ -251,7 +260,7 @@
             DiscreteOps discreteOps;
             synchronized (mInMemoryLock) {
                 discreteOps = mDiscreteOps;
-                mDiscreteOps = new DiscreteOps();
+                mDiscreteOps = new DiscreteOps(discreteOps.mChainIdOffset);
                 mCachedOps = null;
             }
             deleteOldDiscreteHistoryFilesLocked();
@@ -265,16 +274,109 @@
             long beginTimeMillis, long endTimeMillis,
             @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter,
             @Nullable String packageNameFilter, @Nullable String[] opNamesFilter,
-            @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
+            @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter,
+            Set<String> attributionExemptPkgs) {
+        boolean assembleChains = attributionExemptPkgs != null;
         DiscreteOps discreteOps = getAllDiscreteOps();
+        ArrayMap<Integer, AttributionChain> attributionChains = new ArrayMap<>();
+        if (assembleChains) {
+            attributionChains = createAttributionChains(discreteOps, attributionExemptPkgs);
+        }
         beginTimeMillis = max(beginTimeMillis, Instant.now().minus(sDiscreteHistoryCutoff,
                 ChronoUnit.MILLIS).toEpochMilli());
         discreteOps.filter(beginTimeMillis, endTimeMillis, filter, uidFilter, packageNameFilter,
-                opNamesFilter, attributionTagFilter, flagsFilter);
-        discreteOps.applyToHistoricalOps(result);
+                opNamesFilter, attributionTagFilter, flagsFilter, attributionChains);
+        discreteOps.applyToHistoricalOps(result, attributionChains);
         return;
     }
 
+    private int readLargestChainIdFromDiskLocked() {
+        final File[] files = mDiscreteAccessDir.listFiles();
+        if (files != null && files.length > 0) {
+            File latestFile = null;
+            long latestFileTimestamp = 0;
+            for (File f : files) {
+                final String fileName = f.getName();
+                if (!fileName.endsWith(DISCRETE_HISTORY_FILE_SUFFIX)) {
+                    continue;
+                }
+                long timestamp = Long.valueOf(fileName.substring(0,
+                        fileName.length() - DISCRETE_HISTORY_FILE_SUFFIX.length()));
+                if (latestFileTimestamp < timestamp) {
+                    latestFile = f;
+                    latestFileTimestamp = timestamp;
+                }
+            }
+            if (latestFile == null) {
+                return 0;
+            }
+            FileInputStream stream;
+            try {
+                stream = new FileInputStream(latestFile);
+            } catch (FileNotFoundException e) {
+                return 0;
+            }
+            try {
+                TypedXmlPullParser parser = Xml.resolvePullParser(stream);
+                XmlUtils.beginDocument(parser, TAG_HISTORY);
+
+                final int largestChainId = parser.getAttributeInt(null, ATTR_LARGEST_CHAIN_ID, 0);
+                return largestChainId;
+            } catch (Throwable t) {
+                return 0;
+            } finally {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                }
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    private ArrayMap<Integer, AttributionChain> createAttributionChains(
+            DiscreteOps discreteOps, Set<String> attributionExemptPkgs) {
+        ArrayMap<Integer, AttributionChain> chains = new ArrayMap<>();
+        int nUids = discreteOps.mUids.size();
+        for (int uidNum = 0; uidNum < nUids; uidNum++) {
+            ArrayMap<String, DiscretePackageOps> pkgs = discreteOps.mUids.valueAt(uidNum).mPackages;
+            int uid = discreteOps.mUids.keyAt(uidNum);
+            int nPackages = pkgs.size();
+            for (int pkgNum = 0; pkgNum < nPackages; pkgNum++) {
+                ArrayMap<Integer, DiscreteOp> ops = pkgs.valueAt(pkgNum).mPackageOps;
+                String pkg = pkgs.keyAt(pkgNum);
+                int nOps = ops.size();
+                for (int opNum = 0; opNum < nOps; opNum++) {
+                    ArrayMap<String, List<DiscreteOpEvent>> attrOps =
+                            ops.valueAt(opNum).mAttributedOps;
+                    int op = ops.keyAt(opNum);
+                    int nAttrOps = attrOps.size();
+                    for (int attrOpNum = 0; attrOpNum < nAttrOps; attrOpNum++) {
+                        List<DiscreteOpEvent> opEvents = attrOps.valueAt(attrOpNum);
+                        String attributionTag = attrOps.keyAt(attrOpNum);
+                        int nOpEvents = opEvents.size();
+                        for (int opEventNum = 0; opEventNum < nOpEvents; opEventNum++) {
+                            DiscreteOpEvent event = opEvents.get(opEventNum);
+                            if (event == null
+                                    || event.mAttributionChainId == ATTRIBUTION_CHAIN_ID_NONE) {
+                                continue;
+                            }
+
+                            if (!chains.containsKey(event.mAttributionChainId)) {
+                                chains.put(event.mAttributionChainId,
+                                        new AttributionChain(attributionExemptPkgs));
+                            }
+                            chains.get(event.mAttributionChainId)
+                                    .addEvent(pkg, uid, attributionTag, op, event);
+                        }
+                    }
+                }
+            }
+        }
+        return chains;
+    }
+
     private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
         synchronized (mOnDiskLock) {
             long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
@@ -301,7 +403,7 @@
     void clearHistory() {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
-                mDiscreteOps = new DiscreteOps();
+                mDiscreteOps = new DiscreteOps(0);
             }
             clearOnDiskHistoryLocked();
         }
@@ -340,7 +442,11 @@
         String[] opNamesFilter = dumpOp == OP_NONE ? null
                 : new String[]{AppOpsManager.opToPublicName(dumpOp)};
         discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter,
-                opNamesFilter, attributionTagFilter, OP_FLAGS_ALL);
+                opNamesFilter, attributionTagFilter, OP_FLAGS_ALL, new ArrayMap<>());
+        pw.print(prefix);
+        pw.print("Largest chain id: ");
+        pw.print(mDiscreteOps.mLargestChainId);
+        pw.println();
         discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
     }
 
@@ -351,14 +457,14 @@
     }
 
     private DiscreteOps getAllDiscreteOps() {
-        DiscreteOps discreteOps = new DiscreteOps();
+        DiscreteOps discreteOps = new DiscreteOps(0);
 
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
                 discreteOps.merge(mDiscreteOps);
             }
             if (mCachedOps == null) {
-                mCachedOps = new DiscreteOps();
+                mCachedOps = new DiscreteOps(0);
                 readDiscreteOpsFromDisk(mCachedOps);
             }
             discreteOps.merge(mCachedOps);
@@ -366,11 +472,143 @@
         }
     }
 
+    /**
+     * Represents a chain of usages, each attributing its usage to the one before it
+     */
+    private static final class AttributionChain {
+        private static final class OpEvent {
+            String mPkgName;
+            int mUid;
+            String mAttributionTag;
+            int mOpCode;
+            DiscreteOpEvent mOpEvent;
+
+            OpEvent(String pkgName, int uid, String attributionTag, int opCode,
+                    DiscreteOpEvent event) {
+                mPkgName = pkgName;
+                mUid = uid;
+                mAttributionTag = attributionTag;
+                mOpCode = opCode;
+                mOpEvent = event;
+            }
+
+            public boolean matches(String pkgName, int uid, String attributionTag, int opCode,
+                    DiscreteOpEvent event) {
+                return Objects.equals(pkgName, mPkgName) && mUid == uid
+                        && Objects.equals(attributionTag, mAttributionTag) && mOpCode == opCode
+                        && mOpEvent.mAttributionChainId == event.mAttributionChainId
+                        && mOpEvent.mAttributionFlags == event.mAttributionFlags
+                        && mOpEvent.mNoteTime == event.mNoteTime;
+            }
+
+            public boolean packageOpEquals(OpEvent other) {
+                return Objects.equals(other.mPkgName, mPkgName) && other.mUid == mUid
+                        && Objects.equals(other.mAttributionTag, mAttributionTag)
+                        && mOpCode == other.mOpCode;
+            }
+
+            public boolean equalsExceptDuration(OpEvent other) {
+                if (other.mOpEvent.mNoteDuration == mOpEvent.mNoteDuration) {
+                    return false;
+                }
+                return packageOpEquals(other) && mOpEvent.equalsExceptDuration(other.mOpEvent);
+            }
+        }
+
+        ArrayList<OpEvent> mChain = new ArrayList<>();
+        Set<String> mExemptPkgs;
+        OpEvent mStartEvent = null;
+        OpEvent mLastVisibleEvent = null;
+
+        AttributionChain(Set<String> exemptPkgs) {
+            mExemptPkgs = exemptPkgs;
+        }
+
+        boolean isComplete() {
+            return !mChain.isEmpty() && getStart() != null && isEnd(mChain.get(mChain.size() - 1));
+        }
+
+        boolean isStart(String pkgName, int uid, String attributionTag, int op,
+                DiscreteOpEvent opEvent) {
+            if (mStartEvent == null || opEvent == null) {
+                return false;
+            }
+            return mStartEvent.matches(pkgName, uid, attributionTag, op, opEvent);
+        }
+
+        private OpEvent getStart() {
+            return mChain.isEmpty() || !isStart(mChain.get(0)) ? null : mChain.get(0);
+        }
+
+        private OpEvent getLastVisible() {
+            // Search all nodes but the first one, which is the start node
+            for (int i = mChain.size() - 1; i > 0; i--) {
+                OpEvent event = mChain.get(i);
+                if (!mExemptPkgs.contains(event.mPkgName)) {
+                    return event;
+                }
+            }
+            return null;
+        }
+
+        void addEvent(String pkgName, int uid, String attributionTag, int op,
+                DiscreteOpEvent opEvent) {
+            OpEvent event = new OpEvent(pkgName, uid, attributionTag, op, opEvent);
+
+            // check if we have a matching event, without duration, replacing duration otherwise
+            for (int i = 0; i < mChain.size(); i++) {
+                OpEvent item = mChain.get(i);
+                if (item.equalsExceptDuration(event)) {
+                    if (event.mOpEvent.mNoteDuration != -1) {
+                        item.mOpEvent = event.mOpEvent;
+                    }
+                    return;
+                }
+            }
+
+            if (mChain.isEmpty() || isEnd(event)) {
+                mChain.add(event);
+            } else if (isStart(event)) {
+                mChain.add(0, event);
+
+            } else {
+                for (int i = 0; i < mChain.size(); i++) {
+                    OpEvent currEvent = mChain.get(i);
+                    if ((!isStart(currEvent)
+                            && currEvent.mOpEvent.mNoteTime > event.mOpEvent.mNoteTime)
+                            || i == mChain.size() - 1 && isEnd(currEvent)) {
+                        mChain.add(i, event);
+                        break;
+                    } else if (i == mChain.size() - 1) {
+                        mChain.add(event);
+                        break;
+                    }
+                }
+            }
+            mStartEvent = isComplete() ? getStart() : null;
+            mLastVisibleEvent = isComplete() ? getLastVisible() : null;
+        }
+
+        private boolean isEnd(OpEvent event) {
+            return event != null
+                    && (event.mOpEvent.mAttributionFlags & ATTRIBUTION_FLAG_ACCESSOR) != 0;
+        }
+
+        private boolean isStart(OpEvent event) {
+            return event != null
+                    && (event.mOpEvent.mAttributionFlags & ATTRIBUTION_FLAG_RECEIVER) != 0;
+        }
+    }
+
     private final class DiscreteOps {
         ArrayMap<Integer, DiscreteUidOps> mUids;
+        int mChainIdOffset;
+        int mLargestChainId;
 
-        DiscreteOps() {
+        DiscreteOps(int chainIdOffset) {
             mUids = new ArrayMap<>();
+            mChainIdOffset = chainIdOffset;
+            mLargestChainId = chainIdOffset;
         }
 
         boolean isEmpty() {
@@ -378,6 +616,7 @@
         }
 
         void merge(DiscreteOps other) {
+            mLargestChainId = max(mLargestChainId, other.mLargestChainId);
             int nUids = other.mUids.size();
             for (int i = 0; i < nUids; i++) {
                 int uid = other.mUids.keyAt(i);
@@ -390,14 +629,27 @@
                 @Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
                 @AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
                 @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
+            int offsetChainId = attributionChainId;
+            if (attributionChainId != ATTRIBUTION_CHAIN_ID_NONE) {
+                offsetChainId = attributionChainId + mChainIdOffset;
+                if (offsetChainId > mLargestChainId) {
+                    mLargestChainId = offsetChainId;
+                } else if (offsetChainId < 0) {
+                    // handle overflow
+                    offsetChainId = 0;
+                    mLargestChainId = 0;
+                    mChainIdOffset = -1 * attributionChainId;
+                }
+            }
             getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
-                    uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
+                    uidState, accessTime, accessDuration, attributionFlags, offsetChainId);
         }
 
         private void filter(long beginTimeMillis, long endTimeMillis,
                 @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter,
                 @Nullable String packageNameFilter, @Nullable String[] opNamesFilter,
-                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
+                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter,
+                ArrayMap<Integer, AttributionChain> attributionChains) {
             if ((filter & FILTER_BY_UID) != 0) {
                 ArrayMap<Integer, DiscreteUidOps> uids = new ArrayMap<>();
                 uids.put(uidFilter, getOrCreateDiscreteUidOps(uidFilter));
@@ -406,7 +658,8 @@
             int nUids = mUids.size();
             for (int i = nUids - 1; i >= 0; i--) {
                 mUids.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter, packageNameFilter,
-                        opNamesFilter, attributionTagFilter, flagsFilter);
+                        opNamesFilter, attributionTagFilter, flagsFilter, mUids.keyAt(i),
+                        attributionChains);
                 if (mUids.valueAt(i).isEmpty()) {
                     mUids.removeAt(i);
                 }
@@ -429,10 +682,11 @@
             }
         }
 
-        private void applyToHistoricalOps(AppOpsManager.HistoricalOps result) {
+        private void applyToHistoricalOps(AppOpsManager.HistoricalOps result,
+                ArrayMap<Integer, AttributionChain> attributionChains) {
             int nUids = mUids.size();
             for (int i = 0; i < nUids; i++) {
-                mUids.valueAt(i).applyToHistory(result, mUids.keyAt(i));
+                mUids.valueAt(i).applyToHistory(result, mUids.keyAt(i), attributionChains);
             }
         }
 
@@ -442,6 +696,7 @@
             out.startDocument(null, true);
             out.startTag(null, TAG_HISTORY);
             out.attributeInt(null, ATTR_VERSION, CURRENT_VERSION);
+            out.attributeInt(null, ATTR_LARGEST_CHAIN_ID, mLargestChainId);
 
             int nUids = mUids.size();
             for (int i = 0; i < nUids; i++) {
@@ -476,8 +731,13 @@
         }
 
         private void readFromFile(File f, long beginTimeMillis) {
+            FileInputStream stream;
             try {
-                FileInputStream stream = new FileInputStream(f);
+                stream = new FileInputStream(f);
+            } catch (FileNotFoundException e) {
+                return;
+            }
+            try {
                 TypedXmlPullParser parser = Xml.resolvePullParser(stream);
                 XmlUtils.beginDocument(parser, TAG_HISTORY);
 
@@ -487,7 +747,6 @@
                 if (version != CURRENT_VERSION) {
                     throw new IllegalStateException("Dropping unsupported discrete history " + f);
                 }
-
                 int depth = parser.getDepth();
                 while (XmlUtils.nextElementWithin(parser, depth)) {
                     if (TAG_UID.equals(parser.getName())) {
@@ -498,8 +757,12 @@
             } catch (Throwable t) {
                 Slog.e(TAG, "Failed to read file " + f.getName() + " " + t.getMessage() + " "
                         + Arrays.toString(t.getStackTrace()));
+            } finally {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                }
             }
-
         }
     }
 
@@ -590,7 +853,8 @@
         private void filter(long beginTimeMillis, long endTimeMillis,
                 @AppOpsManager.HistoricalOpsRequestFilter int filter,
                 @Nullable String packageNameFilter, @Nullable String[] opNamesFilter,
-                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
+                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter,
+                int currentUid, ArrayMap<Integer, AttributionChain> attributionChains) {
             if ((filter & FILTER_BY_PACKAGE_NAME) != 0) {
                 ArrayMap<String, DiscretePackageOps> packages = new ArrayMap<>();
                 packages.put(packageNameFilter, getOrCreateDiscretePackageOps(packageNameFilter));
@@ -599,7 +863,8 @@
             int nPackages = mPackages.size();
             for (int i = nPackages - 1; i >= 0; i--) {
                 mPackages.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter, opNamesFilter,
-                        attributionTagFilter, flagsFilter);
+                        attributionTagFilter, flagsFilter, currentUid, mPackages.keyAt(i),
+                        attributionChains);
                 if (mPackages.valueAt(i).isEmpty()) {
                     mPackages.removeAt(i);
                 }
@@ -634,10 +899,12 @@
             return result;
         }
 
-        private void applyToHistory(AppOpsManager.HistoricalOps result, int uid) {
+        private void applyToHistory(AppOpsManager.HistoricalOps result, int uid,
+                @NonNull ArrayMap<Integer, AttributionChain> attributionChains) {
             int nPackages = mPackages.size();
             for (int i = 0; i < nPackages; i++) {
-                mPackages.valueAt(i).applyToHistory(result, uid, mPackages.keyAt(i));
+                mPackages.valueAt(i).applyToHistory(result, uid, mPackages.keyAt(i),
+                        attributionChains);
             }
         }
 
@@ -705,7 +972,8 @@
         private void filter(long beginTimeMillis, long endTimeMillis,
                 @AppOpsManager.HistoricalOpsRequestFilter int filter,
                 @Nullable String[] opNamesFilter, @Nullable String attributionTagFilter,
-                @AppOpsManager.OpFlags int flagsFilter) {
+                @AppOpsManager.OpFlags int flagsFilter, int currentUid, String currentPkgName,
+                ArrayMap<Integer, AttributionChain> attributionChains) {
             int nOps = mPackageOps.size();
             for (int i = nOps - 1; i >= 0; i--) {
                 int opId = mPackageOps.keyAt(i);
@@ -715,7 +983,8 @@
                     continue;
                 }
                 mPackageOps.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter,
-                        attributionTagFilter, flagsFilter);
+                        attributionTagFilter, flagsFilter, currentUid, currentPkgName,
+                        mPackageOps.keyAt(i), attributionChains);
                 if (mPackageOps.valueAt(i).isEmpty()) {
                     mPackageOps.removeAt(i);
                 }
@@ -739,11 +1008,12 @@
         }
 
         private void applyToHistory(AppOpsManager.HistoricalOps result, int uid,
-                @NonNull String packageName) {
+                @NonNull String packageName,
+                @NonNull ArrayMap<Integer, AttributionChain> attributionChains) {
             int nPackageOps = mPackageOps.size();
             for (int i = 0; i < nPackageOps; i++) {
                 mPackageOps.valueAt(i).applyToHistory(result, uid, packageName,
-                        mPackageOps.keyAt(i));
+                        mPackageOps.keyAt(i), attributionChains);
             }
         }
 
@@ -802,7 +1072,9 @@
 
         private void filter(long beginTimeMillis, long endTimeMillis,
                 @AppOpsManager.HistoricalOpsRequestFilter int filter,
-                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) {
+                @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter,
+                int currentUid, String currentPkgName, int currentOp,
+                ArrayMap<Integer, AttributionChain> attributionChains) {
             if ((filter & FILTER_BY_ATTRIBUTION_TAG) != 0) {
                 ArrayMap<String, List<DiscreteOpEvent>> attributedOps = new ArrayMap<>();
                 attributedOps.put(attributionTagFilter,
@@ -814,7 +1086,9 @@
             for (int i = nTags - 1; i >= 0; i--) {
                 String tag = mAttributedOps.keyAt(i);
                 List<DiscreteOpEvent> list = mAttributedOps.valueAt(i);
-                list = filterEventsList(list, beginTimeMillis, endTimeMillis, flagsFilter);
+                list = filterEventsList(list, beginTimeMillis, endTimeMillis, flagsFilter,
+                        currentUid, currentPkgName, currentOp, mAttributedOps.keyAt(i),
+                        attributionChains);
                 mAttributedOps.put(tag, list);
                 if (list.size() == 0) {
                     mAttributedOps.removeAt(i);
@@ -876,7 +1150,8 @@
         }
 
         private void applyToHistory(AppOpsManager.HistoricalOps result, int uid,
-                @NonNull String packageName, int op) {
+                @NonNull String packageName, int op,
+                @NonNull ArrayMap<Integer, AttributionChain> attributionChains) {
             int nOps = mAttributedOps.size();
             for (int i = 0; i < nOps; i++) {
                 String tag = mAttributedOps.keyAt(i);
@@ -884,9 +1159,21 @@
                 int nEvents = events.size();
                 for (int j = 0; j < nEvents; j++) {
                     DiscreteOpEvent event = events.get(j);
+                    AppOpsManager.OpEventProxyInfo proxy = null;
+                    if (event.mAttributionChainId != ATTRIBUTION_CHAIN_ID_NONE
+                            && attributionChains != null) {
+                        AttributionChain chain = attributionChains.get(event.mAttributionChainId);
+                        if (chain != null && chain.isComplete()
+                                && chain.isStart(packageName, uid, tag, op, event)
+                                && chain.mLastVisibleEvent != null) {
+                            AttributionChain.OpEvent proxyEvent = chain.mLastVisibleEvent;
+                            proxy = new AppOpsManager.OpEventProxyInfo(proxyEvent.mUid,
+                                    proxyEvent.mPkgName, proxyEvent.mAttributionTag);
+                        }
+                    }
                     result.addDiscreteAccess(op, uid, packageName, tag, event.mUidState,
                             event.mOpFlag, discretizeTimeStamp(event.mNoteTime),
-                            discretizeDuration(event.mNoteDuration));
+                            discretizeDuration(event.mNoteDuration), proxy);
                 }
             }
         }
@@ -981,6 +1268,13 @@
             mAttributionChainId = attributionChainId;
         }
 
+        public boolean equalsExceptDuration(DiscreteOpEvent o) {
+            return mNoteTime == o.mNoteTime && mUidState == o.mUidState && mOpFlag == o.mOpFlag
+                    && mAttributionFlags == o.mAttributionFlags
+                    && mAttributionChainId == o.mAttributionChainId;
+
+        }
+
         private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
                 @NonNull Date date, @NonNull String prefix) {
             pw.print(prefix);
@@ -1063,11 +1357,20 @@
     }
 
     private static List<DiscreteOpEvent> filterEventsList(List<DiscreteOpEvent> list,
-            long beginTimeMillis, long endTimeMillis, @AppOpsManager.OpFlags int flagsFilter) {
+            long beginTimeMillis, long endTimeMillis, @AppOpsManager.OpFlags int flagsFilter,
+            int currentUid, String currentPackageName, int currentOp, String currentAttrTag,
+            ArrayMap<Integer, AttributionChain> attributionChains) {
         int n = list.size();
         List<DiscreteOpEvent> result = new ArrayList<>(n);
         for (int i = 0; i < n; i++) {
             DiscreteOpEvent event = list.get(i);
+            AttributionChain chain = attributionChains.get(event.mAttributionChainId);
+            // If we have an attribution chain, and this event isn't the beginning node, remove it
+            if (chain != null && !chain.isStart(currentPackageName, currentUid, currentAttrTag,
+                    currentOp, event) && chain.isComplete()
+                    && event.mAttributionChainId != ATTRIBUTION_CHAIN_ID_NONE) {
+                continue;
+            }
             if ((event.mOpFlag & flagsFilter) != 0
                     && event.mNoteTime + event.mNoteDuration > beginTimeMillis
                     && event.mNoteTime < endTimeMillis) {
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index dd5df50..2c68aaf 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -209,6 +209,7 @@
         mMode = other.mMode;
         mBaseSnapshotInterval = other.mBaseSnapshotInterval;
         mIntervalCompressionMultiplier = other.mIntervalCompressionMultiplier;
+        mDiscreteRegistry = other.mDiscreteRegistry;
     }
 
     void systemReady(@NonNull ContentResolver resolver) {
@@ -369,7 +370,7 @@
             @Nullable String attributionTag, @Nullable String[] opNames,
             @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter,
             long beginTimeMillis, long endTimeMillis, @OpFlags int flags,
-            @NonNull RemoteCallback callback) {
+            String[] attributionExemptedPackages, @NonNull RemoteCallback callback) {
         if (!isApiEnabled()) {
             callback.sendResult(new Bundle());
             return;
@@ -395,7 +396,7 @@
         if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) {
             mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis,
                     endTimeMillis, filter, uid, packageName, opNames, attributionTag,
-                    flags);
+                    flags, new ArraySet<>(attributionExemptedPackages));
         }
 
         final Bundle payload = new Bundle();
@@ -406,7 +407,8 @@
     void getHistoricalOps(int uid, @Nullable String packageName, @Nullable String attributionTag,
             @Nullable String[] opNames, @OpHistoryFlags int historyFlags,
             @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis,
-            @OpFlags int flags, @NonNull RemoteCallback callback) {
+            @OpFlags int flags, @Nullable String[] attributionExemptPkgs,
+            @NonNull RemoteCallback callback) {
         if (!isApiEnabled()) {
             callback.sendResult(new Bundle());
             return;
@@ -428,7 +430,8 @@
 
         if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) {
             mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis,
-                    endTimeMillis, filter, uid, packageName, opNames, attributionTag, flags);
+                    endTimeMillis, filter, uid, packageName, opNames, attributionTag, flags,
+                    new ArraySet<>(attributionExemptPkgs));
         }
 
         if ((historyFlags & HISTORY_FLAG_AGGREGATE) != 0) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index a5bb0f4..0981f18 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -866,7 +866,7 @@
     private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
         final boolean hasEnrolled = !getEnrolledFaces(mSensorId, targetUserId).isEmpty();
         final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
-                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId,
+                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId,
                 hasEnrolled, mAuthenticatorIds);
         mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() {
             @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
index 70e2033..5343d0d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
@@ -34,38 +34,23 @@
     private static final String TAG = "FaceUpdateActiveUserClient";
     private static final String FACE_DATA_DIR = "facedata";
 
-    private final int mCurrentUserId;
     private final boolean mHasEnrolledBiometrics;
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
 
     FaceUpdateActiveUserClient(@NonNull Context context,
-            @NonNull LazyDaemon<IBiometricsFace> lazyDaemon,  int userId, @NonNull String owner,
-            int sensorId, int currentUserId, boolean hasEnrolledBIometrics,
+            @NonNull LazyDaemon<IBiometricsFace> lazyDaemon, int userId, @NonNull String owner,
+            int sensorId, boolean hasEnrolledBiometrics,
             @NonNull Map<Integer, Long> authenticatorIds) {
         super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner,
                 0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN,
                 BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN);
-        mCurrentUserId = currentUserId;
-        mHasEnrolledBiometrics = hasEnrolledBIometrics;
+        mHasEnrolledBiometrics = hasEnrolledBiometrics;
         mAuthenticatorIds = authenticatorIds;
     }
 
     @Override
     public void start(@NonNull Callback callback) {
         super.start(callback);
-
-        if (mCurrentUserId == getTargetUserId()) {
-            Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId");
-            try {
-                mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics
-                        ? getFreshDaemon().getAuthenticatorId().value : 0L);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to refresh authenticatorId", e);
-            }
-            callback.onClientFinished(this, true /* success */);
-            return;
-        }
-
         startHalOperation();
     }
 
@@ -85,7 +70,10 @@
         }
 
         try {
-            getFreshDaemon().setActiveUser(getTargetUserId(), storePath.getAbsolutePath());
+            final IBiometricsFace daemon = getFreshDaemon();
+            daemon.setActiveUser(getTargetUserId(), storePath.getAbsolutePath());
+            mAuthenticatorIds.put(getTargetUserId(),
+                    mHasEnrolledBiometrics ? daemon.getAuthenticatorId().value : 0L);
             mCallback.onClientFinished(this, true /* success */);
         } catch (RemoteException e) {
             Slog.e(TAG, "Failed to setActiveUser: " + e);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
index f1f9456..0ae2e38 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
@@ -80,8 +80,7 @@
             // No framework constant available
             return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
         } else if (aidlAcquiredInfo == AcquiredInfo.IMMOBILE) {
-            // No framework constant available
-            return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
+            return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
         } else if (aidlAcquiredInfo == AcquiredInfo.RETRYING_CAPTURE) {
             // No framework constant available
             return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index c237535..de6e494 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -603,6 +603,10 @@
 
         try (InputStream in = new BufferedInputStream(new FileInputStream(overridesFile))) {
             Overrides overrides = com.android.server.compat.overrides.XmlParser.read(in);
+            if (overrides == null) {
+                Slog.w(TAG, "Parsing " + overridesFile.getPath() + " failed");
+                return;
+            }
             for (ChangeOverrides changeOverrides : overrides.getChangeOverrides()) {
                 long changeId = changeOverrides.getChangeId();
                 CompatChange compatChange = mChanges.get(changeId);
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 19e858c..0d317f4 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -36,6 +36,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Slog;
@@ -359,7 +360,7 @@
 
     private ApplicationInfo getApplicationInfo(String packageName, int userId) {
         return LocalServices.getService(PackageManagerInternal.class).getApplicationInfo(
-                packageName, 0, userId, userId);
+                packageName, 0, Process.myUid(), userId);
     }
 
     private void killPackage(String packageName) {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index aeb1893..e6210b2 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -45,6 +45,7 @@
 import android.app.compat.CompatChanges;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.location.Criteria;
 import android.location.GeocoderParams;
 import android.location.Geofence;
@@ -91,6 +92,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
@@ -134,6 +136,8 @@
 import com.android.server.location.provider.PassiveLocationProviderManager;
 import com.android.server.location.provider.StationaryThrottlingLocationProvider;
 import com.android.server.location.provider.proxy.ProxyLocationProvider;
+import com.android.server.location.settings.LocationSettings;
+import com.android.server.location.settings.LocationUserSettings;
 import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 import java.io.FileDescriptor;
@@ -270,6 +274,8 @@
 
         mGeofenceManager = new GeofenceManager(mContext, injector);
 
+        mInjector.getLocationSettings().registerLocationUserSettingsListener(
+                this::onLocationUserSettingsChanged);
         mInjector.getSettingsHelper().addOnLocationEnabledChangedListener(
                 this::onLocationModeChanged);
         mInjector.getSettingsHelper().addIgnoreSettingsAllowlistChangedListener(
@@ -476,6 +482,25 @@
         }
     }
 
+    private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings,
+            LocationUserSettings newSettings) {
+        if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) {
+            boolean enabled = newSettings.isAdasGnssLocationEnabled();
+
+            if (D) {
+                Log.d(TAG, "[u" + userId + "] adas gnss location enabled = " + enabled);
+            }
+
+            EVENT_LOG.logAdasLocationEnabled(userId, enabled);
+
+            Intent intent = new Intent(LocationManager.ACTION_ADAS_GNSS_ENABLED_CHANGED)
+                    .putExtra(LocationManager.EXTRA_ADAS_GNSS_ENABLED, enabled)
+                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+                    .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+            mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+        }
+    }
+
     private void onLocationModeChanged(int userId) {
         boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId);
         LocationManager.invalidateLocalLocationEnabledCaches();
@@ -661,7 +686,7 @@
         // clients in the system process must have an attribution tag set
         Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null);
 
-        request = validateLocationRequest(request, identity);
+        request = validateLocationRequest(provider, request, identity);
 
         LocationProviderManager manager = getLocationProviderManager(provider);
         Preconditions.checkArgument(manager != null,
@@ -687,7 +712,7 @@
                     new IllegalArgumentException());
         }
 
-        request = validateLocationRequest(request, identity);
+        request = validateLocationRequest(provider, request, identity);
 
         LocationProviderManager manager = getLocationProviderManager(provider);
         Preconditions.checkArgument(manager != null,
@@ -725,7 +750,7 @@
             }
         }
 
-        request = validateLocationRequest(request, identity);
+        request = validateLocationRequest(provider, request, identity);
 
         LocationProviderManager manager = getLocationProviderManager(provider);
         Preconditions.checkArgument(manager != null,
@@ -734,33 +759,27 @@
         manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent);
     }
 
-    private LocationRequest validateLocationRequest(LocationRequest request,
+    private LocationRequest validateLocationRequest(String provider, LocationRequest request,
             CallerIdentity identity) {
+        // validate unsanitized request
         if (!request.getWorkSource().isEmpty()) {
             mContext.enforceCallingOrSelfPermission(
                     permission.UPDATE_DEVICE_STATS,
                     "setting a work source requires " + permission.UPDATE_DEVICE_STATS);
         }
-        if (request.isHiddenFromAppOps()) {
-            mContext.enforceCallingOrSelfPermission(
-                    permission.UPDATE_APP_OPS_STATS,
-                    "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS);
-        }
-        if (request.isLocationSettingsIgnored()) {
-            mContext.enforceCallingOrSelfPermission(
-                    permission.WRITE_SECURE_SETTINGS,
-                    "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS);
-        }
 
+        // sanitize request
         LocationRequest.Builder sanitized = new LocationRequest.Builder(request);
 
-        if (CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) {
-            if (request.isLowPower()) {
-                mContext.enforceCallingOrSelfPermission(
-                        permission.LOCATION_HARDWARE,
-                        "low power request requires " + permission.LOCATION_HARDWARE);
-            }
-        } else {
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                && GPS_PROVIDER.equals(provider)
+                && ArrayUtils.contains(mContext.getResources().getStringArray(
+                com.android.internal.R.array.config_locationDriverAssistancePackageNames),
+                identity.getPackageName())) {
+            sanitized.setAdasGnssBypass(true);
+        }
+
+        if (!CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) {
             if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE)
                     != PERMISSION_GRANTED) {
                 sanitized.setLowPower(false);
@@ -786,7 +805,52 @@
         }
         sanitized.setWorkSource(workSource);
 
-        return sanitized.build();
+        request = sanitized.build();
+
+        // validate sanitized request
+        boolean isLocationProvider = mLocalService.isProvider(null, identity);
+
+        if (request.isLowPower() && CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS,
+                identity.getUid())) {
+            mContext.enforceCallingOrSelfPermission(
+                    permission.LOCATION_HARDWARE,
+                    "low power request requires " + permission.LOCATION_HARDWARE);
+        }
+        if (request.isHiddenFromAppOps()) {
+            mContext.enforceCallingOrSelfPermission(
+                    permission.UPDATE_APP_OPS_STATS,
+                    "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS);
+        }
+        if (request.isAdasGnssBypass()) {
+            if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                throw new IllegalArgumentException(
+                        "adas gnss bypass requests are only allowed on automotive devices");
+            }
+            if (!GPS_PROVIDER.equals(provider)) {
+                throw new IllegalArgumentException(
+                        "adas gnss bypass requests are only allowed on the \"gps\" provider");
+            }
+            if (!ArrayUtils.contains(mContext.getResources().getStringArray(
+                    com.android.internal.R.array.config_locationDriverAssistancePackageNames),
+                    identity.getPackageName())) {
+                throw new SecurityException(
+                        "only verified adas packages may use adas gnss bypass requests");
+            }
+            if (!isLocationProvider) {
+                mContext.enforceCallingOrSelfPermission(
+                        permission.WRITE_SECURE_SETTINGS,
+                        "adas gnss bypass requires " + permission.WRITE_SECURE_SETTINGS);
+            }
+        }
+        if (request.isLocationSettingsIgnored()) {
+            if (!isLocationProvider) {
+                mContext.enforceCallingOrSelfPermission(
+                        permission.WRITE_SECURE_SETTINGS,
+                        "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS);
+            }
+        }
+
+        return request;
     }
 
     @Override
@@ -834,7 +898,7 @@
         // clients in the system process must have an attribution tag set
         Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null);
 
-        request = validateLastLocationRequest(request);
+        request = validateLastLocationRequest(provider, request, identity);
 
         LocationProviderManager manager = getLocationProviderManager(provider);
         if (manager == null) {
@@ -844,16 +908,58 @@
         return manager.getLastLocation(request, identity, permissionLevel);
     }
 
-    private LastLocationRequest validateLastLocationRequest(LastLocationRequest request) {
+    private LastLocationRequest validateLastLocationRequest(String provider,
+            LastLocationRequest request,
+            CallerIdentity identity) {
+        // sanitize request
+        LastLocationRequest.Builder sanitized = new LastLocationRequest.Builder(request);
+
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                && GPS_PROVIDER.equals(provider)
+                && ArrayUtils.contains(mContext.getResources().getStringArray(
+                com.android.internal.R.array.config_locationDriverAssistancePackageNames),
+                identity.getPackageName())) {
+            sanitized.setAdasGnssBypass(true);
+        }
+
+        request = sanitized.build();
+
+        // validate request
+        boolean isLocationProvider = mLocalService.isProvider(null, identity);
+
         if (request.isHiddenFromAppOps()) {
             mContext.enforceCallingOrSelfPermission(
                     permission.UPDATE_APP_OPS_STATS,
                     "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS);
         }
+
+        if (request.isAdasGnssBypass()) {
+            if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                throw new IllegalArgumentException(
+                        "adas gnss bypass requests are only allowed on automotive devices");
+            }
+            if (!GPS_PROVIDER.equals(provider)) {
+                throw new IllegalArgumentException(
+                        "adas gnss bypass requests are only allowed on the \"gps\" provider");
+            }
+            if (!ArrayUtils.contains(mContext.getResources().getStringArray(
+                    com.android.internal.R.array.config_locationDriverAssistancePackageNames),
+                    identity.getPackageName())) {
+                throw new SecurityException(
+                        "only verified adas packages may use adas gnss bypass requests");
+            }
+            if (!isLocationProvider) {
+                mContext.enforceCallingOrSelfPermission(
+                        permission.WRITE_SECURE_SETTINGS,
+                        "adas gnss bypass requires " + permission.WRITE_SECURE_SETTINGS);
+            }
+        }
         if (request.isLocationSettingsIgnored()) {
-            mContext.enforceCallingOrSelfPermission(
-                    permission.WRITE_SECURE_SETTINGS,
-                    "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS);
+            if (!isLocationProvider) {
+                mContext.enforceCallingOrSelfPermission(
+                        permission.WRITE_SECURE_SETTINGS,
+                        "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS);
+            }
         }
 
         return request;
@@ -1126,6 +1232,24 @@
     }
 
     @Override
+    public void setAdasGnssLocationEnabledForUser(boolean enabled, int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, false, false, "setAdasGnssLocationEnabledForUser", null);
+
+        mContext.enforceCallingOrSelfPermission(permission.WRITE_SECURE_SETTINGS, null);
+
+        mInjector.getLocationSettings().updateUserSettings(userId,
+                settings -> settings.withAdasGnssLocationEnabled(enabled));
+    }
+
+    @Override
+    public boolean isAdasGnssLocationEnabledForUser(int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, false, false, "isAdasGnssLocationEnabledForUser", null);
+        return mInjector.getLocationSettings().getUserSettings(userId).isAdasGnssLocationEnabled();
+    }
+
+    @Override
     public boolean isProviderEnabledForUser(String provider, int userId) {
         return mLocalService.isProviderEnabledForUser(provider, userId);
     }
@@ -1555,11 +1679,12 @@
         }
     }
 
-    private static class SystemInjector implements Injector {
+    private static final class SystemInjector implements Injector {
 
         private final Context mContext;
 
         private final UserInfoHelper mUserInfoHelper;
+        private final LocationSettings mLocationSettings;
         private final AlarmHelper mAlarmHelper;
         private final SystemAppOpsHelper mAppOpsHelper;
         private final SystemLocationPermissionsHelper mLocationPermissionsHelper;
@@ -1584,6 +1709,7 @@
             mContext = context;
 
             mUserInfoHelper = userInfoHelper;
+            mLocationSettings = new LocationSettings(context);
             mAlarmHelper = new SystemAlarmHelper(context);
             mAppOpsHelper = new SystemAppOpsHelper(context);
             mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context,
@@ -1621,6 +1747,11 @@
         }
 
         @Override
+        public LocationSettings getLocationSettings() {
+            return mLocationSettings;
+        }
+
+        @Override
         public AlarmHelper getAlarmHelper() {
             return mAlarmHelper;
         }
diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java
index 9378493..b65338d 100644
--- a/services/core/java/com/android/server/location/LocationShellCommand.java
+++ b/services/core/java/com/android/server/location/LocationShellCommand.java
@@ -17,6 +17,7 @@
 package com.android.server.location;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.location.Criteria;
 import android.location.Location;
 import android.location.provider.ProviderProperties;
@@ -60,6 +61,14 @@
                 handleSetLocationEnabled();
                 return 0;
             }
+            case "is-adas-gnss-location-enabled": {
+                handleIsAdasGnssLocationEnabled();
+                return 0;
+            }
+            case "set-adas-gnss-location-enabled": {
+                handleSetAdasGnssLocationEnabled();
+                return 0;
+            }
             case "providers": {
                 String command = getNextArgRequired();
                 return parseProvidersCommand(command);
@@ -134,6 +143,52 @@
         mService.setLocationEnabledForUser(enabled, userId);
     }
 
+    private void handleIsAdasGnssLocationEnabled() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            throw new IllegalStateException("command only recognized on automotive devices");
+        }
+
+        int userId = UserHandle.USER_CURRENT_OR_SELF;
+
+        do {
+            String option = getNextOption();
+            if (option == null) {
+                break;
+            }
+            if ("--user".equals(option)) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                throw new IllegalArgumentException("Unknown option: " + option);
+            }
+        } while (true);
+
+        getOutPrintWriter().println(mService.isAdasGnssLocationEnabledForUser(userId));
+    }
+
+    private void handleSetAdasGnssLocationEnabled() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            throw new IllegalStateException("command only recognized on automotive devices");
+        }
+
+        boolean enabled = Boolean.parseBoolean(getNextArgRequired());
+
+        int userId = UserHandle.USER_CURRENT_OR_SELF;
+
+        do {
+            String option = getNextOption();
+            if (option == null) {
+                break;
+            }
+            if ("--user".equals(option)) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                throw new IllegalArgumentException("Unknown option: " + option);
+            }
+        } while (true);
+
+        mService.setAdasGnssLocationEnabledForUser(enabled, userId);
+    }
+
     private void handleAddTestProvider() {
         String provider = getNextArgRequired();
 
@@ -297,6 +352,14 @@
         pw.println("  set-location-enabled true|false [--user <USER_ID>]");
         pw.println("    Sets the master location switch enabled state. If no user is specified,");
         pw.println("    the current user is assumed.");
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            pw.println("  is-adas-gnss-location-enabled [--user <USER_ID>]");
+            pw.println("    Gets the ADAS GNSS location enabled state. If no user is specified,");
+            pw.println("    the current user is assumed.");
+            pw.println("  set-adas-gnss-location-enabled true|false [--user <USER_ID>]");
+            pw.println("    Sets the ADAS GNSS location enabled state. If no user is specified,");
+            pw.println("    the current user is assumed.");
+        }
         pw.println("  providers");
         pw.println("    The providers command is followed by a subcommand, as listed below:");
         pw.println();
@@ -323,9 +386,8 @@
         pw.println("      Common commands that may be supported by the gps provider, depending on");
         pw.println("      hardware and software configurations:");
         pw.println("        delete_aiding_data - requests deletion of any predictive aiding data");
-        pw.println("        force_time_injection - requests NTP time injection to chipset");
-        pw.println("        force_psds_injection - "
-                + "requests predictive aiding data injection to chipset");
-        pw.println("        request_power_stats - requests GNSS power stats update from chipset");
+        pw.println("        force_time_injection - requests NTP time injection");
+        pw.println("        force_psds_injection - requests predictive aiding data injection");
+        pw.println("        request_power_stats - requests GNSS power stats update");
     }
 }
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index e6d25ec..db2a43f 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -55,19 +55,20 @@
 
     private static final int EVENT_USER_SWITCHED = 1;
     private static final int EVENT_LOCATION_ENABLED = 2;
-    private static final int EVENT_PROVIDER_ENABLED = 3;
-    private static final int EVENT_PROVIDER_MOCKED = 4;
-    private static final int EVENT_PROVIDER_CLIENT_REGISTER = 5;
-    private static final int EVENT_PROVIDER_CLIENT_UNREGISTER = 6;
-    private static final int EVENT_PROVIDER_CLIENT_FOREGROUND = 7;
-    private static final int EVENT_PROVIDER_CLIENT_BACKGROUND = 8;
-    private static final int EVENT_PROVIDER_CLIENT_PERMITTED = 9;
-    private static final int EVENT_PROVIDER_CLIENT_UNPERMITTED = 10;
-    private static final int EVENT_PROVIDER_UPDATE_REQUEST = 11;
-    private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 12;
-    private static final int EVENT_PROVIDER_DELIVER_LOCATION = 13;
-    private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 14;
-    private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 15;
+    private static final int EVENT_ADAS_LOCATION_ENABLED = 3;
+    private static final int EVENT_PROVIDER_ENABLED = 4;
+    private static final int EVENT_PROVIDER_MOCKED = 5;
+    private static final int EVENT_PROVIDER_CLIENT_REGISTER = 6;
+    private static final int EVENT_PROVIDER_CLIENT_UNREGISTER = 7;
+    private static final int EVENT_PROVIDER_CLIENT_FOREGROUND = 8;
+    private static final int EVENT_PROVIDER_CLIENT_BACKGROUND = 9;
+    private static final int EVENT_PROVIDER_CLIENT_PERMITTED = 10;
+    private static final int EVENT_PROVIDER_CLIENT_UNPERMITTED = 11;
+    private static final int EVENT_PROVIDER_UPDATE_REQUEST = 12;
+    private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 13;
+    private static final int EVENT_PROVIDER_DELIVER_LOCATION = 14;
+    private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 15;
+    private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 16;
 
     @GuardedBy("mAggregateStats")
     private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats;
@@ -116,6 +117,11 @@
         addLogEvent(EVENT_LOCATION_ENABLED, userId, enabled);
     }
 
+    /** Logs a location enabled/disabled event. */
+    public void logAdasLocationEnabled(int userId, boolean enabled) {
+        addLogEvent(EVENT_ADAS_LOCATION_ENABLED, userId, enabled);
+    }
+
     /** Logs a location provider enabled/disabled event. */
     public void logProviderEnabled(String provider, int userId, boolean enabled) {
         addLogEvent(EVENT_PROVIDER_ENABLED, provider, userId, enabled);
@@ -219,6 +225,9 @@
                 return new UserSwitchedEvent(timeDelta, (Integer) args[0], (Integer) args[1]);
             case EVENT_LOCATION_ENABLED:
                 return new LocationEnabledEvent(timeDelta, (Integer) args[0], (Boolean) args[1]);
+            case EVENT_ADAS_LOCATION_ENABLED:
+                return new LocationAdasEnabledEvent(timeDelta, (Integer) args[0],
+                        (Boolean) args[1]);
             case EVENT_PROVIDER_ENABLED:
                 return new ProviderEnabledEvent(timeDelta, (String) args[0], (Integer) args[1],
                         (Boolean) args[2]);
@@ -517,6 +526,23 @@
         }
     }
 
+    private static final class LocationAdasEnabledEvent extends LogEvent {
+
+        private final int mUserId;
+        private final boolean mEnabled;
+
+        LocationAdasEnabledEvent(long timeDelta, int userId, boolean enabled) {
+            super(timeDelta);
+            mUserId = userId;
+            mEnabled = enabled;
+        }
+
+        @Override
+        public String getLogString() {
+            return "adas location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled");
+        }
+    }
+
     /**
      * Aggregate statistics for a single package under a single provider.
      */
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 1cccf08..f3dcfbb 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -771,10 +771,10 @@
         boolean enabled = mContext.getSystemService(LocationManager.class)
                 .isLocationEnabledForUser(UserHandle.CURRENT);
 
-        // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
+        // .. but enable anyway, if there's an active bypass request (e.g. ELS or ADAS)
         enabled |= (mProviderRequest != null
                 && mProviderRequest.isActive()
-                && mProviderRequest.isLocationSettingsIgnored());
+                && mProviderRequest.isBypass());
 
         // ... and, finally, disable anyway, if device is being shut down
         enabled &= !mShutdown;
diff --git a/services/core/java/com/android/server/location/injector/Injector.java b/services/core/java/com/android/server/location/injector/Injector.java
index b035118..173fd13 100644
--- a/services/core/java/com/android/server/location/injector/Injector.java
+++ b/services/core/java/com/android/server/location/injector/Injector.java
@@ -17,6 +17,7 @@
 package com.android.server.location.injector;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.location.settings.LocationSettings;
 
 /**
  * Injects various location dependencies so that they may be controlled by tests.
@@ -27,6 +28,9 @@
     /** Returns a UserInfoHelper. */
     UserInfoHelper getUserInfoHelper();
 
+    /** Returns a LocationSettings. */
+    LocationSettings getLocationSettings();
+
     /** Returns an AlarmHelper. */
     AlarmHelper getAlarmHelper();
 
diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
index c315da4..3e8da7d 100644
--- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
@@ -670,8 +670,6 @@
         }
     }
 
-
-
     private static class PackageTagsListSetting extends DeviceConfigSetting {
 
         private final Supplier<ArrayMap<String, ArraySet<String>>> mBaseValuesSupplier;
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 8d335b8..43886f7 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -113,6 +113,8 @@
 import com.android.server.location.injector.UserInfoHelper.UserListener;
 import com.android.server.location.listeners.ListenerMultiplexer;
 import com.android.server.location.listeners.RemoteListenerRegistration;
+import com.android.server.location.settings.LocationSettings;
+import com.android.server.location.settings.LocationUserSettings;
 
 import java.io.FileDescriptor;
 import java.lang.annotation.Retention;
@@ -549,6 +551,19 @@
         }
 
         @GuardedBy("mLock")
+        final boolean onAdasGnssLocationEnabledChanged(int userId) {
+            if (Build.IS_DEBUGGABLE) {
+                Preconditions.checkState(Thread.holdsLock(mLock));
+            }
+
+            if (getIdentity().getUserId() == userId) {
+                return onProviderLocationRequestChanged();
+            }
+
+            return false;
+        }
+
+        @GuardedBy("mLock")
         final boolean onForegroundChanged(int uid, boolean foreground) {
             if (Build.IS_DEBUGGABLE) {
                 Preconditions.checkState(Thread.holdsLock(mLock));
@@ -592,8 +607,8 @@
             onHighPowerUsageChanged();
             updateService();
 
-            // if location settings ignored has changed then the active state may have changed
-            return oldRequest.isLocationSettingsIgnored() != newRequest.isLocationSettingsIgnored();
+            // if bypass state has changed then the active state may have changed
+            return oldRequest.isBypass() != newRequest.isBypass();
         }
 
         private LocationRequest calculateProviderLocationRequest() {
@@ -616,9 +631,24 @@
                 if (!mSettingsHelper.getIgnoreSettingsAllowlist().contains(
                         getIdentity().getPackageName(), getIdentity().getAttributionTag())
                         && !mLocationManagerInternal.isProvider(null, getIdentity())) {
-                    builder.setLocationSettingsIgnored(false);
                     locationSettingsIgnored = false;
                 }
+
+                builder.setLocationSettingsIgnored(locationSettingsIgnored);
+            }
+
+            boolean adasGnssBypass = baseRequest.isAdasGnssBypass();
+            if (adasGnssBypass) {
+                // if we are not currently allowed use adas gnss bypass, disable it
+                if (!GPS_PROVIDER.equals(mName)) {
+                    Log.e(TAG, "adas gnss bypass request received in non-gps provider");
+                    adasGnssBypass = false;
+                } else if (!mLocationSettings.getUserSettings(
+                        getIdentity().getUserId()).isAdasGnssLocationEnabled()) {
+                    adasGnssBypass = false;
+                }
+
+                builder.setAdasGnssBypass(adasGnssBypass);
             }
 
             if (!locationSettingsIgnored && !isThrottlingExempt()) {
@@ -769,7 +799,7 @@
                     Location lastLocation = getLastLocationUnsafe(
                             getIdentity().getUserId(),
                             getPermissionLevel(),
-                            getRequest().isLocationSettingsIgnored(),
+                            getRequest().isBypass(),
                             maxLocationAgeMs);
                     if (lastLocation != null) {
                         executeOperation(acceptLocationChange(LocationResult.wrap(lastLocation)));
@@ -1114,7 +1144,7 @@
             Location lastLocation = getLastLocationUnsafe(
                     getIdentity().getUserId(),
                     getPermissionLevel(),
-                    getRequest().isLocationSettingsIgnored(),
+                    getRequest().isBypass(),
                     MAX_CURRENT_LOCATION_AGE_MS);
             if (lastLocation != null) {
                 executeOperation(acceptLocationChange(LocationResult.wrap(lastLocation)));
@@ -1267,6 +1297,7 @@
     private final CopyOnWriteArrayList<IProviderRequestListener> mProviderRequestListeners;
 
     protected final LocationManagerInternal mLocationManagerInternal;
+    protected final LocationSettings mLocationSettings;
     protected final SettingsHelper mSettingsHelper;
     protected final UserInfoHelper mUserHelper;
     protected final AlarmHelper mAlarmHelper;
@@ -1280,6 +1311,8 @@
     protected final LocationFudger mLocationFudger;
 
     private final UserListener mUserChangedListener = this::onUserChanged;
+    private final LocationSettings.LocationUserSettingsListener mLocationUserSettingsListener =
+            this::onLocationUserSettingsChanged;
     private final UserSettingChangedListener mLocationEnabledChangedListener =
             this::onLocationEnabledChanged;
     private final GlobalSettingChangedListener mBackgroundThrottlePackageWhitelistChangedListener =
@@ -1332,6 +1365,7 @@
 
         mLocationManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(LocationManagerInternal.class));
+        mLocationSettings = injector.getLocationSettings();
         mSettingsHelper = injector.getSettingsHelper();
         mUserHelper = injector.getUserInfoHelper();
         mAlarmHelper = injector.getAlarmHelper();
@@ -1362,6 +1396,7 @@
             mStateChangedListener = listener;
 
             mUserHelper.addListener(mUserChangedListener);
+            mLocationSettings.registerLocationUserSettingsListener(mLocationUserSettingsListener);
             mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener);
 
             final long identity = Binder.clearCallingIdentity();
@@ -1389,6 +1424,7 @@
             }
 
             mUserHelper.removeListener(mUserChangedListener);
+            mLocationSettings.unregisterLocationUserSettingsListener(mLocationUserSettingsListener);
             mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener);
 
             // if external entities are registering listeners it's their responsibility to
@@ -1550,7 +1586,7 @@
 
     public @Nullable Location getLastLocation(LastLocationRequest request,
             CallerIdentity identity, @PermissionLevel int permissionLevel) {
-        if (!isActive(request.isLocationSettingsIgnored(), identity)) {
+        if (!isActive(request.isBypass(), identity)) {
             return null;
         }
 
@@ -1564,7 +1600,7 @@
                 getLastLocationUnsafe(
                         identity.getUserId(),
                         permissionLevel,
-                        request.isLocationSettingsIgnored(),
+                        request.isBypass(),
                         Long.MAX_VALUE),
                 permissionLevel);
 
@@ -1584,7 +1620,7 @@
      * location if necessary.
      */
     public @Nullable Location getLastLocationUnsafe(int userId,
-            @PermissionLevel int permissionLevel, boolean ignoreLocationSettings,
+            @PermissionLevel int permissionLevel, boolean isBypass,
             long maximumAgeMs) {
         if (userId == UserHandle.USER_ALL) {
             // find the most recent location across all users
@@ -1592,7 +1628,7 @@
             final int[] runningUserIds = mUserHelper.getRunningUserIds();
             for (int i = 0; i < runningUserIds.length; i++) {
                 Location next = getLastLocationUnsafe(runningUserIds[i], permissionLevel,
-                        ignoreLocationSettings, maximumAgeMs);
+                        isBypass, maximumAgeMs);
                 if (lastLocation == null || (next != null && next.getElapsedRealtimeNanos()
                         > lastLocation.getElapsedRealtimeNanos())) {
                     lastLocation = next;
@@ -1601,7 +1637,7 @@
             return lastLocation;
         } else if (userId == UserHandle.USER_CURRENT) {
             return getLastLocationUnsafe(mUserHelper.getCurrentUserId(), permissionLevel,
-                    ignoreLocationSettings, maximumAgeMs);
+                    isBypass, maximumAgeMs);
         }
 
         Preconditions.checkArgument(userId >= 0);
@@ -1613,7 +1649,7 @@
             if (lastLocation == null) {
                 location = null;
             } else {
-                location = lastLocation.get(permissionLevel, ignoreLocationSettings);
+                location = lastLocation.get(permissionLevel, isBypass);
             }
         }
 
@@ -1925,7 +1961,7 @@
         // provider, under the assumption that once we send the request off, the provider will
         // immediately attempt to deliver a new location satisfying that request.
         long delayMs;
-        if (!oldRequest.isLocationSettingsIgnored() && newRequest.isLocationSettingsIgnored()) {
+        if (!oldRequest.isBypass() && newRequest.isBypass()) {
             delayMs = 0;
         } else if (newRequest.getIntervalMillis() > oldRequest.getIntervalMillis()) {
             // if the interval has increased, tell the provider immediately, so it can save power
@@ -2002,12 +2038,12 @@
             return false;
         }
 
-        boolean locationSettingsIgnored = registration.getRequest().isLocationSettingsIgnored();
-        if (!isActive(locationSettingsIgnored, registration.getIdentity())) {
+        boolean isBypass = registration.getRequest().isBypass();
+        if (!isActive(isBypass, registration.getIdentity())) {
             return false;
         }
 
-        if (!locationSettingsIgnored) {
+        if (!isBypass) {
             switch (mLocationPowerSaveModeHelper.getLocationPowerSaveMode()) {
                 case LOCATION_MODE_FOREGROUND_ONLY:
                     if (!registration.isForeground()) {
@@ -2036,15 +2072,15 @@
         return true;
     }
 
-    private boolean isActive(boolean locationSettingsIgnored, CallerIdentity identity) {
+    private boolean isActive(boolean isBypass, CallerIdentity identity) {
         if (identity.isSystemServer()) {
-            if (!locationSettingsIgnored) {
+            if (!isBypass) {
                 if (!isEnabled(mUserHelper.getCurrentUserId())) {
                     return false;
                 }
             }
         } else {
-            if (!locationSettingsIgnored) {
+            if (!isBypass) {
                 if (!isEnabled(identity.getUserId())) {
                     return false;
                 }
@@ -2071,6 +2107,7 @@
         long intervalMs = ProviderRequest.INTERVAL_DISABLED;
         int quality = LocationRequest.QUALITY_LOW_POWER;
         long maxUpdateDelayMs = Long.MAX_VALUE;
+        boolean adasGnssBypass = false;
         boolean locationSettingsIgnored = false;
         boolean lowPower = true;
 
@@ -2086,6 +2123,7 @@
             intervalMs = min(request.getIntervalMillis(), intervalMs);
             quality = min(request.getQuality(), quality);
             maxUpdateDelayMs = min(request.getMaxUpdateDelayMillis(), maxUpdateDelayMs);
+            adasGnssBypass |= request.isAdasGnssBypass();
             locationSettingsIgnored |= request.isLocationSettingsIgnored();
             lowPower &= request.isLowPower();
         }
@@ -2123,6 +2161,7 @@
                 .setIntervalMillis(intervalMs)
                 .setQuality(quality)
                 .setMaxUpdateDelayMillis(maxUpdateDelayMs)
+                .setAdasGnssBypass(adasGnssBypass)
                 .setLocationSettingsIgnored(locationSettingsIgnored)
                 .setLowPower(lowPower)
                 .setWorkSource(workSource)
@@ -2191,6 +2230,16 @@
         }
     }
 
+    private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings,
+            LocationUserSettings newSettings) {
+        if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) {
+            synchronized (mLock) {
+                updateRegistrations(
+                        registration -> registration.onAdasGnssLocationEnabledChanged(userId));
+            }
+        }
+    }
+
     private void onLocationEnabledChanged(int userId) {
         synchronized (mLock) {
             if (mState == STATE_STOPPED) {
@@ -2560,16 +2609,16 @@
         }
 
         public @Nullable Location get(@PermissionLevel int permissionLevel,
-                boolean ignoreLocationSettings) {
+                boolean isBypass) {
             switch (permissionLevel) {
                 case PERMISSION_FINE:
-                    if (ignoreLocationSettings) {
+                    if (isBypass) {
                         return mFineBypassLocation;
                     } else {
                         return mFineLocation;
                     }
                 case PERMISSION_COARSE:
-                    if (ignoreLocationSettings) {
+                    if (isBypass) {
                         return mCoarseBypassLocation;
                     } else {
                         return mCoarseLocation;
diff --git a/services/core/java/com/android/server/location/settings/LocationSettings.java b/services/core/java/com/android/server/location/settings/LocationSettings.java
new file mode 100644
index 0000000..d521538
--- /dev/null
+++ b/services/core/java/com/android/server/location/settings/LocationSettings.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.settings;
+
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
+
+import android.content.Context;
+import android.os.Environment;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.FgThread;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Function;
+
+/**
+ * Accessor for location user settings. Ensure there is only ever one instance as multiple instances
+ * don't play nicely with each other.
+ */
+public class LocationSettings {
+
+    /** Listens for changes to location user settings. */
+    public interface LocationUserSettingsListener {
+        /** Invoked when location user settings have changed for the given user. */
+        void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings,
+                LocationUserSettings newSettings);
+    }
+
+    private static final String LOCATION_DIRNAME = "location";
+    private static final String LOCATION_SETTINGS_FILENAME = "settings";
+
+    final Context mContext;
+
+    @GuardedBy("mUserSettings")
+    private final SparseArray<LocationUserSettingsStore> mUserSettings;
+    private final CopyOnWriteArrayList<LocationUserSettingsListener> mUserSettingsListeners;
+
+    public LocationSettings(Context context) {
+        mContext = context;
+        mUserSettings = new SparseArray<>(1);
+        mUserSettingsListeners = new CopyOnWriteArrayList<>();
+    }
+
+    /** Registers a listener for changes to location user settings. */
+    public final void registerLocationUserSettingsListener(LocationUserSettingsListener listener) {
+        mUserSettingsListeners.add(listener);
+    }
+
+    /** Unregisters a listener for changes to location user settings. */
+    public final void unregisterLocationUserSettingsListener(
+            LocationUserSettingsListener listener) {
+        mUserSettingsListeners.remove(listener);
+    }
+
+    protected File getUserSettingsDir(int userId) {
+        return Environment.getDataSystemDeDirectory(userId);
+    }
+
+    protected LocationUserSettingsStore createUserSettingsStore(int userId, File file) {
+        return new LocationUserSettingsStore(userId, file);
+    }
+
+    private LocationUserSettingsStore getUserSettingsStore(int userId) {
+        synchronized (mUserSettings) {
+            LocationUserSettingsStore settingsStore = mUserSettings.get(userId);
+            if (settingsStore == null) {
+                File file = new File(new File(getUserSettingsDir(userId), LOCATION_DIRNAME),
+                        LOCATION_SETTINGS_FILENAME);
+                settingsStore = createUserSettingsStore(userId, file);
+                mUserSettings.put(userId, settingsStore);
+            }
+            return settingsStore;
+        }
+    }
+
+    /** Retrieves the current state of location user settings. */
+    public final LocationUserSettings getUserSettings(int userId) {
+        return getUserSettingsStore(userId).get();
+    }
+
+    /** Updates the current state of location user settings for the given user. */
+    public final void updateUserSettings(int userId,
+            Function<LocationUserSettings, LocationUserSettings> updater) {
+        getUserSettingsStore(userId).update(updater);
+    }
+
+    @VisibleForTesting
+    final void flushFiles() throws InterruptedException {
+        synchronized (mUserSettings) {
+            int size = mUserSettings.size();
+            for (int i = 0; i < size; i++) {
+                mUserSettings.valueAt(i).flushFile();
+            }
+        }
+    }
+
+    @VisibleForTesting
+    final void deleteFiles() throws InterruptedException {
+        synchronized (mUserSettings) {
+            int size = mUserSettings.size();
+            for (int i = 0; i < size; i++) {
+                mUserSettings.valueAt(i).deleteFile();
+            }
+        }
+    }
+
+    protected final void fireListeners(int userId, LocationUserSettings oldSettings,
+            LocationUserSettings newSettings) {
+        for (LocationUserSettingsListener listener : mUserSettingsListeners) {
+            listener.onLocationUserSettingsChanged(userId, oldSettings, newSettings);
+        }
+    }
+
+    class LocationUserSettingsStore extends SettingsStore<LocationUserSettings> {
+
+        protected final int mUserId;
+
+        LocationUserSettingsStore(int userId, File file) {
+            super(file);
+            mUserId = userId;
+        }
+
+        @Override
+        protected LocationUserSettings read(int version, DataInput in) throws IOException {
+            return filterSettings(LocationUserSettings.read(mContext.getResources(), version, in));
+        }
+
+        @Override
+        protected void write(DataOutput out, LocationUserSettings settings) throws IOException {
+            settings.write(out);
+        }
+
+        @Override
+        public void update(Function<LocationUserSettings, LocationUserSettings> updater) {
+            super.update(settings -> filterSettings(updater.apply(settings)));
+        }
+
+        @Override
+        protected void onChange(LocationUserSettings oldSettings,
+                LocationUserSettings newSettings) {
+            FgThread.getExecutor().execute(() -> fireListeners(mUserId, oldSettings, newSettings));
+        }
+
+        private LocationUserSettings filterSettings(LocationUserSettings settings) {
+            if (settings.isAdasGnssLocationEnabled()
+                    && !mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)) {
+                // prevent non-automotive devices from ever enabling this
+                settings = settings.withAdasGnssLocationEnabled(false);
+            }
+            return settings;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/location/settings/LocationUserSettings.java b/services/core/java/com/android/server/location/settings/LocationUserSettings.java
new file mode 100644
index 0000000..283255e
--- /dev/null
+++ b/services/core/java/com/android/server/location/settings/LocationUserSettings.java
@@ -0,0 +1,98 @@
+/*
+ * 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.location.settings;
+
+import android.content.res.Resources;
+
+import com.android.internal.R;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Objects;
+
+/** Holds the state of location user settings. */
+public final class LocationUserSettings implements SettingsStore.VersionedSettings {
+
+    // remember to bump this version code and add the appropriate upgrade logic whenever the format
+    // is changed.
+    private static final int VERSION = 1;
+
+    private final boolean mAdasGnssLocationEnabled;
+
+    private LocationUserSettings(boolean adasGnssLocationEnabled) {
+        mAdasGnssLocationEnabled = adasGnssLocationEnabled;
+    }
+
+    @Override
+    public int getVersion() {
+        return VERSION;
+    }
+
+    public boolean isAdasGnssLocationEnabled() {
+        return mAdasGnssLocationEnabled;
+    }
+
+    /** Returns an instance with ADAS GNSS location enabled state set as given. */
+    public LocationUserSettings withAdasGnssLocationEnabled(boolean adasEnabled) {
+        if (adasEnabled == mAdasGnssLocationEnabled) {
+            return this;
+        }
+
+        return new LocationUserSettings(adasEnabled);
+    }
+
+    void write(DataOutput out) throws IOException {
+        out.writeBoolean(mAdasGnssLocationEnabled);
+    }
+
+    static LocationUserSettings read(Resources resources, int version, DataInput in)
+            throws IOException {
+        boolean adasGnssLocationEnabled;
+
+        // upgrade code goes here. remember to bump the version field when changing the format
+        switch (version) {
+            default:
+                // set all fields to defaults
+                adasGnssLocationEnabled = resources.getBoolean(
+                        R.bool.config_defaultAdasGnssLocationEnabled);
+                break;
+            case 1:
+                adasGnssLocationEnabled = in.readBoolean();
+                // fall through
+        }
+
+        return new LocationUserSettings(adasGnssLocationEnabled);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof LocationUserSettings)) {
+            return false;
+        }
+        LocationUserSettings that = (LocationUserSettings) o;
+        return mAdasGnssLocationEnabled == that.mAdasGnssLocationEnabled;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAdasGnssLocationEnabled);
+    }
+}
diff --git a/services/core/java/com/android/server/location/settings/SettingsStore.java b/services/core/java/com/android/server/location/settings/SettingsStore.java
new file mode 100644
index 0000000..01338a3
--- /dev/null
+++ b/services/core/java/com/android/server/location/settings/SettingsStore.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.settings;
+
+import static com.android.server.location.LocationManagerService.TAG;
+import static com.android.server.location.settings.SettingsStore.VersionedSettings.VERSION_DOES_NOT_EXIST;
+
+import android.util.AtomicFile;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.Preconditions;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Function;
+
+/** Base class for read/write/versioning functionality for storing persistent settings to a file. */
+abstract class SettingsStore<T extends SettingsStore.VersionedSettings> {
+
+    interface VersionedSettings {
+        /** Represents that the settings do not exist. */
+        int VERSION_DOES_NOT_EXIST = Integer.MAX_VALUE;
+
+        /** Must always return a version number less than {@link #VERSION_DOES_NOT_EXIST}. */
+        int getVersion();
+    }
+
+    private final AtomicFile mFile;
+
+    @GuardedBy("this")
+    private boolean mInitialized;
+    @GuardedBy("this")
+    private T mCache;
+
+    protected SettingsStore(File file) {
+        mFile = new AtomicFile(file);
+    }
+
+    /**
+     * Must be implemented to read in a settings instance, and upgrade to the appropriate version
+     * where necessary. If the provided version is {@link VersionedSettings#VERSION_DOES_NOT_EXIST}
+     * then the DataInput will be empty, and the method should return a settings instance with all
+     * settings set to the default value.
+     */
+    protected abstract T read(int version, DataInput in) throws IOException;
+
+    /**
+     * Must be implemented to write the given settings to the given DataOutput.
+     */
+    protected abstract void write(DataOutput out, T settings) throws IOException;
+
+    /**
+     * Invoked when settings change, and while holding the internal lock. If used to invoke
+     * listeners, ensure they are not invoked while holding the lock (ie, asynchronously).
+     */
+    protected abstract void onChange(T oldSettings, T newSettings);
+
+    public final synchronized void initializeCache() {
+        if (!mInitialized) {
+            if (mFile.exists()) {
+                try (DataInputStream is = new DataInputStream(mFile.openRead())) {
+                    mCache = read(is.readInt(), is);
+                    Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST);
+                } catch (IOException e) {
+                    Log.e(TAG, "error reading location settings (" + mFile
+                            + "), falling back to defaults", e);
+                }
+            }
+
+            if (mCache == null) {
+                try {
+                    mCache = read(VERSION_DOES_NOT_EXIST,
+                            new DataInputStream(new ByteArrayInputStream(new byte[0])));
+                    Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST);
+                } catch (IOException e) {
+                    throw new AssertionError(e);
+                }
+            }
+
+            mInitialized = true;
+        }
+    }
+
+    public final synchronized T get() {
+        initializeCache();
+        return mCache;
+    }
+
+    public synchronized void update(Function<T, T> updater) {
+        initializeCache();
+
+        T oldSettings = mCache;
+        T newSettings = Objects.requireNonNull(updater.apply(oldSettings));
+        if (oldSettings.equals(newSettings)) {
+            return;
+        }
+
+        mCache = newSettings;
+        Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST);
+
+        writeLazily(newSettings);
+
+        onChange(oldSettings, newSettings);
+    }
+
+    @VisibleForTesting
+    synchronized void flushFile() throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        BackgroundThread.getExecutor().execute(latch::countDown);
+        latch.await();
+    }
+
+    @VisibleForTesting
+    synchronized void deleteFile() throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        BackgroundThread.getExecutor().execute(() -> {
+            mFile.delete();
+            latch.countDown();
+        });
+        latch.await();
+    }
+
+    private void writeLazily(T settings) {
+        BackgroundThread.getExecutor().execute(() -> {
+            FileOutputStream os = null;
+            try {
+                os = mFile.startWrite();
+                DataOutputStream out = new DataOutputStream(os);
+                out.writeInt(settings.getVersion());
+                write(out, settings);
+                mFile.finishWrite(os);
+            } catch (IOException e) {
+                mFile.failWrite(os);
+                Log.e(TAG, "failure serializing location settings", e);
+            } catch (Throwable e) {
+                mFile.failWrite(os);
+                throw e;
+            }
+        });
+    }
+}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 21f68ae..d791bd6 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1235,11 +1235,7 @@
     final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            synchronized (mUidRulesFirstLock) {
-                synchronized (mNetworkPoliciesSecondLock) {
-                    upgradeWifiMeteredOverrideAL();
-                }
-            }
+            upgradeWifiMeteredOverride();
             // Only need to perform upgrade logic once
             mContext.unregisterReceiver(this);
         }
@@ -2617,34 +2613,43 @@
      * Perform upgrade step of moving any user-defined meterness overrides over
      * into {@link WifiConfiguration}.
      */
-    @GuardedBy({"mNetworkPoliciesSecondLock", "mUidRulesFirstLock"})
-    private void upgradeWifiMeteredOverrideAL() {
-        boolean modified = false;
-        final WifiManager wm = mContext.getSystemService(WifiManager.class);
-        final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
-        for (int i = 0; i < mNetworkPolicy.size(); ) {
-            final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
-            if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
-                    && !policy.inferred) {
-                mNetworkPolicy.removeAt(i);
-                modified = true;
-
-                final String networkId = resolveNetworkId(policy.template.getNetworkId());
-                for (WifiConfiguration config : configs) {
-                    if (Objects.equals(resolveNetworkId(config), networkId)) {
-                        Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint");
-                        config.meteredOverride = policy.metered
-                                ? WifiConfiguration.METERED_OVERRIDE_METERED
-                                : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
-                        wm.updateNetwork(config);
-                    }
+    private void upgradeWifiMeteredOverride() {
+        final ArrayMap<String, Boolean> wifiNetworkIds = new ArrayMap<>();
+        synchronized (mNetworkPoliciesSecondLock) {
+            for (int i = 0; i < mNetworkPolicy.size();) {
+                final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
+                if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
+                        && !policy.inferred) {
+                    mNetworkPolicy.removeAt(i);
+                    wifiNetworkIds.put(policy.template.getNetworkId(), policy.metered);
+                } else {
+                    i++;
                 }
-            } else {
-                i++;
             }
         }
-        if (modified) {
-            writePolicyAL();
+
+        if (wifiNetworkIds.isEmpty()) {
+            return;
+        }
+        final WifiManager wm = mContext.getSystemService(WifiManager.class);
+        final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
+        for (int i = 0; i < configs.size(); ++i) {
+            final WifiConfiguration config = configs.get(i);
+            final String networkId = resolveNetworkId(config);
+            final Boolean metered = wifiNetworkIds.get(networkId);
+            if (metered != null) {
+                Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint");
+                config.meteredOverride = metered
+                        ? WifiConfiguration.METERED_OVERRIDE_METERED
+                        : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
+                wm.updateNetwork(config);
+            }
+        }
+
+        synchronized (mUidRulesFirstLock) {
+            synchronized (mNetworkPoliciesSecondLock) {
+                writePolicyAL();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a3f3a3a..d78fbdb 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -140,6 +140,7 @@
 import android.app.ITransientNotification;
 import android.app.ITransientNotificationCallback;
 import android.app.IUriGrantsManager;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
@@ -549,6 +550,8 @@
     // Used for rate limiting toasts by package.
     private MultiRateLimiter mToastRateLimiter;
 
+    private KeyguardManager mKeyguardManager;
+
     // The last key in this list owns the hardware.
     ArrayList<String> mLights = new ArrayList<>();
 
@@ -2008,6 +2011,11 @@
     }
 
     @VisibleForTesting
+    void setKeyguardManager(KeyguardManager keyguardManager) {
+        mKeyguardManager = keyguardManager;
+    }
+
+    @VisibleForTesting
     ShortcutHelper getShortcutHelper() {
         return mShortcutHelper;
     }
@@ -2653,6 +2661,7 @@
             mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
             mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+            mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
             mZenModeHelper.onSystemReady();
             RoleObserver roleObserver = new RoleObserver(getContext(),
                     getContext().getSystemService(RoleManager.class),
@@ -3806,15 +3815,18 @@
             enforceDeletingChannelHasNoFgService(pkg, callingUser, channelId);
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
                     callingUser, REASON_CHANNEL_REMOVED, null);
-            mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId);
-            // Remove from both recent notification archive and notification history
-            mArchive.removeChannelNotifications(pkg, callingUser, channelId);
-            mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId);
-            mListeners.notifyNotificationChannelChanged(pkg,
-                    UserHandle.getUserHandleForUid(callingUid),
-                    mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
-                    NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-            handleSavePolicyFile();
+            boolean previouslyExisted = mPreferencesHelper.deleteNotificationChannel(
+                    pkg, callingUid, channelId);
+            if (previouslyExisted) {
+                // Remove from both recent notification archive and notification history
+                mArchive.removeChannelNotifications(pkg, callingUser, channelId);
+                mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId);
+                mListeners.notifyNotificationChannelChanged(pkg,
+                        UserHandle.getUserHandleForUid(callingUid),
+                        mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
+                        NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
+                handleSavePolicyFile();
+            }
         }
 
         @Override
@@ -7388,7 +7400,6 @@
         boolean beep = false;
         boolean blink = false;
 
-        final Notification notification = record.getSbn().getNotification();
         final String key = record.getKey();
 
         // Should this notification make noise, vibe, or use the LED?
@@ -7410,7 +7421,7 @@
         if (!record.isUpdate
                 && record.getImportance() > IMPORTANCE_MIN
                 && !suppressedByDnd) {
-            sendAccessibilityEvent(notification, record.getSbn().getPackageName());
+            sendAccessibilityEvent(record);
             sentAccessibilityEvent = true;
         }
 
@@ -7433,7 +7444,7 @@
                 boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
                 if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
                     if (!sentAccessibilityEvent) {
-                        sendAccessibilityEvent(notification, record.getSbn().getPackageName());
+                        sendAccessibilityEvent(record);
                         sentAccessibilityEvent = true;
                     }
                     if (DBG) Slog.v(TAG, "Interrupting!");
@@ -8261,17 +8272,30 @@
         return (x < low) ? low : ((x > high) ? high : x);
     }
 
-    void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
+    void sendAccessibilityEvent(NotificationRecord record) {
         if (!mAccessibilityManager.isEnabled()) {
             return;
         }
 
-        AccessibilityEvent event =
+        final Notification notification = record.getNotification();
+        final CharSequence packageName = record.getSbn().getPackageName();
+        final AccessibilityEvent event =
             AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
         event.setPackageName(packageName);
         event.setClassName(Notification.class.getName());
-        event.setParcelableData(notification);
-        CharSequence tickerText = notification.tickerText;
+        final int visibilityOverride = record.getPackageVisibilityOverride();
+        final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
+                ? notification.visibility : visibilityOverride;
+        final int userId = record.getUser().getIdentifier();
+        final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
+        if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
+            // Emit the public version if we're on the lockscreen and this notification isn't
+            // publicly visible.
+            event.setParcelableData(notification.publicVersion);
+        } else {
+            event.setParcelableData(notification);
+        }
+        final CharSequence tickerText = notification.tickerText;
         if (!TextUtils.isEmpty(tickerText)) {
             event.getText().add(tickerText);
         }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 03676b55..96bde3d 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1126,20 +1126,21 @@
     }
 
     @Override
-    public void deleteNotificationChannel(String pkg, int uid, String channelId) {
+    public boolean deleteNotificationChannel(String pkg, int uid, String channelId) {
         synchronized (mPackagePreferences) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
-                return;
+                return false;
             }
             NotificationChannel channel = r.channels.get(channelId);
             if (channel != null) {
-                deleteNotificationChannelLocked(channel, pkg, uid);
+                return deleteNotificationChannelLocked(channel, pkg, uid);
             }
+            return false;
         }
     }
 
-    private void deleteNotificationChannelLocked(NotificationChannel channel, String pkg, int uid) {
+    private boolean deleteNotificationChannelLocked(NotificationChannel channel, String pkg, int uid) {
         if (!channel.isDeleted()) {
             channel.setDeleted(true);
             channel.setDeletedTimeMs(System.currentTimeMillis());
@@ -1151,7 +1152,9 @@
             if (mAreChannelsBypassingDnd && channel.canBypassDnd()) {
                 updateChannelsBypassingDnd();
             }
+            return true;
         }
+        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index b1d6546..3982593 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -53,7 +53,7 @@
     NotificationChannel getConversationNotificationChannel(String pkg, int uid, String channelId,
             String conversationId, boolean returnParentIfNoConversationChannel,
             boolean includeDeleted);
-    void deleteNotificationChannel(String pkg, int uid, String channelId);
+    boolean deleteNotificationChannel(String pkg, int uid, String channelId);
     void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId);
     void permanentlyDeleteNotificationChannels(String pkg, int uid);
     ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid,
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index a98f113..b144ff2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -417,7 +417,14 @@
             newConfig = mConfig.copy();
             for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
                 ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
-                if (rule.pkg.equals(packageName) && canManageAutomaticZenRule(rule)) {
+                String pkg = rule.pkg != null
+                        ? rule.pkg
+                        : (rule.component != null)
+                                ? rule.component.getPackageName()
+                                : (rule.configurationActivity != null)
+                                        ? rule.configurationActivity.getPackageName()
+                                        : null;
+                if (Objects.equals(pkg, packageName) && canManageAutomaticZenRule(rule)) {
                     newConfig.automaticRules.removeAt(i);
                 }
             }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index c331300..acc83cf 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2799,7 +2799,7 @@
 
     private boolean isApexUpdateAllowed(String apexPackageName) {
         return mPm.getModuleInfo(apexPackageName, 0) != null
-                || SystemConfig.getInstance().getAllowedPartnerApexes().contains(apexPackageName);
+                || SystemConfig.getInstance().getAllowedVendorApexes().contains(apexPackageName);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 463520f..2419873 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21480,6 +21480,8 @@
         // for the uninstall-updates case and restricted profiles, remember the per-
         // user handle installed state
         int[] allUsers;
+        final int freezeUser;
+        final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser;
         /** enabled state of the uninstalled application */
         synchronized (mLock) {
             uninstalledPs = mSettings.getPackageLPr(packageName);
@@ -21524,16 +21526,23 @@
             }
 
             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
-        }
 
-        final int freezeUser;
-        if (isUpdatedSystemApp(uninstalledPs)
-                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
-            // We're downgrading a system app, which will apply to all users, so
-            // freeze them all during the downgrade
-            freezeUser = UserHandle.USER_ALL;
-        } else {
-            freezeUser = removeUser;
+            if (isUpdatedSystemApp(uninstalledPs)
+                    && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
+                // We're downgrading a system app, which will apply to all users, so
+                // freeze them all during the downgrade
+                freezeUser = UserHandle.USER_ALL;
+                enabledStateAndCallerPerUser = new SparseArray<>();
+                for (int i = 0; i < allUsers.length; i++) {
+                    PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
+                    Pair<Integer, String> enabledStateAndCaller =
+                            new Pair<>(userState.enabled, userState.lastDisableAppCaller);
+                    enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller);
+                }
+            } else {
+                freezeUser = removeUser;
+                enabledStateAndCallerPerUser = null;
+            }
         }
 
         synchronized (mInstallLock) {
@@ -21602,6 +21611,19 @@
                     }
                 }
             }
+            if (enabledStateAndCallerPerUser != null) {
+                synchronized (mLock) {
+                    for (int i = 0; i < allUsers.length; i++) {
+                        Pair<Integer, String> enabledStateAndCaller =
+                                enabledStateAndCallerPerUser.get(allUsers[i]);
+                        getPackageSetting(packageName)
+                                .setEnabled(enabledStateAndCaller.first,
+                                        allUsers[i],
+                                        enabledStateAndCaller.second);
+                    }
+                    mSettings.writeAllUsersPackageRestrictionsLPr();
+                }
+            }
         }
 
         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
@@ -28126,8 +28148,8 @@
         }
 
         @Override
-        public void deleteOatArtifactsOfPackage(String packageName) {
-            PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
+        public long deleteOatArtifactsOfPackage(String packageName) {
+            return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 4a68b76..c842ff1 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -955,8 +955,7 @@
                 continue;
             } else if (isApexSessionFailed(apexSession)) {
                 hasFailedApexSession = true;
-                String errorMsg = "APEX activation failed. Check logcat messages from apexd "
-                        + "for more information.";
+                String errorMsg = "APEX activation failed. " + apexSession.errorMessage;
                 if (!TextUtils.isEmpty(apexSession.crashingNativeProcess)) {
                     prepareForLoggingApexdRevert(session, apexSession.crashingNativeProcess);
                     errorMsg = "Session reverted due to crashing native process: "
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index 83d4ce7..b26b694 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -22,6 +22,7 @@
 import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
 import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK;
 
+import android.os.SystemClock;
 import android.util.Slog;
 import android.util.jar.StrictJarFile;
 
@@ -288,7 +289,7 @@
                             ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN),
                     COMPILATION_REASON_MAP.getOrDefault(compilationReason, ArtStatsLog.
                             ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN),
-                    /*timestamp_millis=*/ 0L,
+                    /*timestamp_millis=*/ SystemClock.uptimeMillis(),
                     ArtStatsLog.ART_DATUM_REPORTED__THREAD_TYPE__ART_THREAD_MAIN,
                     kind,
                     value,
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index bad7e5c..dab980a 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -641,7 +641,7 @@
         // Cell Broadcast Receiver
         grantSystemFixedPermissionsToSystemPackage(pm,
                 getDefaultSystemHandlerActivityPackage(pm, Intents.SMS_CB_RECEIVED_ACTION, userId),
-                userId, SMS_PERMISSIONS);
+                userId, SMS_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS);
 
         // Carrier Provisioning Service
         grantPermissionsToSystemPackage(pm,
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index a391dbc..38e9d3e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -5720,10 +5720,8 @@
                 boolean fromDatasource, int attributedOp) {
             // Now let's check the identity chain...
             final int op = AppOpsManager.permissionToOpCode(permission);
-            final int attributionChainId = (startDataDelivery)
-                    ? sAttributionChainIds.incrementAndGet()
-                    : AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
-
+            final int attributionChainId =
+                    getAttributionChainId(startDataDelivery, attributionSource);
             AttributionSource current = attributionSource;
             AttributionSource next = null;
 
@@ -5879,9 +5877,8 @@
                 return PermissionChecker.PERMISSION_HARD_DENIED;
             }
 
-            final int attributionChainId = (startDataDelivery)
-                    ? sAttributionChainIds.incrementAndGet()
-                    : AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
+            final int attributionChainId =
+                    getAttributionChainId(startDataDelivery, attributionSource);
 
             AttributionSource current = attributionSource;
             AttributionSource next = null;
@@ -6064,6 +6061,21 @@
             }
         }
 
+        private static int getAttributionChainId(boolean startDataDelivery,
+                AttributionSource source) {
+            if (source == null || source.getNext() == null || !startDataDelivery) {
+                return AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
+            }
+            int attributionChainId = sAttributionChainIds.incrementAndGet();
+
+            // handle overflow
+            if (attributionChainId < 0) {
+                attributionChainId = 0;
+                sAttributionChainIds.set(0);
+            }
+            return attributionChainId;
+        }
+
         private static @Nullable String resolvePackageName(@NonNull Context context,
                 @NonNull AttributionSource attributionSource) {
             if (attributionSource.getPackageName() != null) {
diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
index d439b94..1d8c64b 100644
--- a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
+++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
@@ -22,6 +22,7 @@
 import android.os.vibrator.StepSegment;
 import android.os.vibrator.VibrationEffectSegment;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -59,6 +60,7 @@
         convertStepsToRamps(segments);
         int newRepeatIndex = addRampDownToZeroAmplitudeSegments(segments, repeatIndex);
         newRepeatIndex = addRampDownToLoop(segments, newRepeatIndex);
+        newRepeatIndex = splitLongRampSegments(info, segments, newRepeatIndex);
         return newRepeatIndex;
     }
 
@@ -210,11 +212,70 @@
         return repeatIndex;
     }
 
+    /**
+     * Split {@link RampSegment} entries that have duration longer than {@link
+     * VibratorInfo#getPwlePrimitiveDurationMax()}.
+     */
+    private int splitLongRampSegments(VibratorInfo info, List<VibrationEffectSegment> segments,
+            int repeatIndex) {
+        int maxDuration = info.getPwlePrimitiveDurationMax();
+        if (maxDuration <= 0) {
+            // No limit set to PWLE primitive duration.
+            return repeatIndex;
+        }
+
+        int segmentCount = segments.size();
+        for (int i = 0; i < segmentCount; i++) {
+            if (!(segments.get(i) instanceof RampSegment)) {
+                continue;
+            }
+            RampSegment ramp = (RampSegment) segments.get(i);
+            int splits = ((int) ramp.getDuration() + maxDuration - 1) / maxDuration;
+            if (splits <= 1) {
+                continue;
+            }
+            segments.remove(i);
+            segments.addAll(i, splitRampSegment(ramp, splits));
+            int addedSegments = splits - 1;
+            if (repeatIndex > i) {
+                repeatIndex += addedSegments;
+            }
+            i += addedSegments;
+            segmentCount += addedSegments;
+        }
+
+        return repeatIndex;
+    }
+
     private static RampSegment apply(StepSegment segment) {
         return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
                 segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
     }
 
+    private static List<RampSegment> splitRampSegment(RampSegment ramp, int splits) {
+        List<RampSegment> ramps = new ArrayList<>(splits);
+        long splitDuration = ramp.getDuration() / splits;
+        float previousAmplitude = ramp.getStartAmplitude();
+        float previousFrequency = ramp.getStartFrequency();
+        long accumulatedDuration = 0;
+
+        for (int i = 1; i < splits; i++) {
+            accumulatedDuration += splitDuration;
+            RampSegment rampSplit = new RampSegment(
+                    previousAmplitude, interpolateAmplitude(ramp, accumulatedDuration),
+                    previousFrequency, interpolateFrequency(ramp, accumulatedDuration),
+                    (int) splitDuration);
+            ramps.add(rampSplit);
+            previousAmplitude = rampSplit.getEndAmplitude();
+            previousFrequency = rampSplit.getEndFrequency();
+        }
+
+        ramps.add(new RampSegment(previousAmplitude, ramp.getEndAmplitude(), previousFrequency,
+                ramp.getEndFrequency(), (int) (ramp.getDuration() - accumulatedDuration)));
+
+        return ramps;
+    }
+
     private static RampSegment createRampDown(float amplitude, float frequency, long duration) {
         return new RampSegment(amplitude, /* endAmplitude= */ 0, frequency, frequency,
                 (int) duration);
@@ -244,4 +305,19 @@
         }
         return false;
     }
+
+    private static float interpolateAmplitude(RampSegment ramp, long duration) {
+        return interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), duration,
+                ramp.getDuration());
+    }
+
+    private static float interpolateFrequency(RampSegment ramp, long duration) {
+        return interpolate(ramp.getStartFrequency(), ramp.getEndFrequency(), duration,
+                ramp.getDuration());
+    }
+
+    private static float interpolate(float start, float end, long duration, long totalDuration) {
+        float position = (float) duration / totalDuration;
+        return start + position * (end - start);
+    }
 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 782e18b..7713320 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -405,20 +405,10 @@
             needsExtraction = wallpaper.primaryColors == null;
         }
 
-        // Let's notify the current values, it's fine if it's null, it just means
-        // that we don't know yet.
-        notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId);
-
         if (needsExtraction) {
             extractColors(wallpaper);
-            synchronized (mLock) {
-                // Don't need to notify if nothing changed.
-                if (wallpaper.primaryColors == null) {
-                    return;
-                }
-            }
-            notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId);
         }
+        notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId);
     }
 
     private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 55d1920..0ad8782 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -38,6 +38,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -277,6 +278,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
+import android.service.contentcapture.ActivityEvent;
 import android.service.dreams.DreamActivity;
 import android.service.dreams.DreamManagerInternal;
 import android.service.voice.IVoiceInteractionSession;
@@ -327,6 +329,7 @@
 import com.android.server.LocalServices;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.am.PendingIntentRecord;
+import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.uri.NeededUriGrants;
@@ -677,8 +680,6 @@
     private boolean mInSizeCompatModeForBounds = false;
 
     // Whether the aspect ratio restrictions applied to the activity bounds in applyAspectRatio().
-    // TODO(b/182268157): Aspect ratio can also be applie in resolveFixedOrientationConfiguration
-    // but that isn't reflected in this boolean.
     private boolean mIsAspectRatioApplied = false;
 
     // Bounds populated in resolveFixedOrientationConfiguration when this activity is letterboxed
@@ -1788,17 +1789,19 @@
 
     /**
      * Evaluate the theme for a starting window.
+     * @param prev Previous activity which may have a starting window.
      * @param originalTheme The original theme which read from activity or application.
      * @param replaceTheme The replace theme which requested from starter.
      * @return Resolved theme.
      */
-    private int evaluateStartingWindowTheme(String pkg, int originalTheme, int replaceTheme) {
+    private int evaluateStartingWindowTheme(ActivityRecord prev, String pkg, int originalTheme,
+            int replaceTheme) {
         // Skip if the package doesn't want a starting window.
-        if (!validateStartingWindowTheme(pkg, originalTheme)) {
+        if (!validateStartingWindowTheme(prev, pkg, originalTheme)) {
             return 0;
         }
         int selectedTheme = originalTheme;
-        if (replaceTheme != 0 && validateStartingWindowTheme(pkg, replaceTheme)) {
+        if (replaceTheme != 0 && validateStartingWindowTheme(prev, pkg, replaceTheme)) {
             // allow to replace theme
             selectedTheme = replaceTheme;
         }
@@ -1835,7 +1838,7 @@
         return LAUNCH_SOURCE_TYPE_APPLICATION;
     }
 
-    private boolean validateStartingWindowTheme(String pkg, int theme) {
+    private boolean validateStartingWindowTheme(ActivityRecord prev, String pkg, int theme) {
         // If this is a translucent window, then don't show a starting window -- the current
         // effect (a full-screen opaque starting window that fades away to the real contents
         // when it is ready) does not work for this.
@@ -1872,7 +1875,11 @@
             return false;
         }
         if (windowDisableStarting && !launchedFromSystemSurface()) {
-            return false;
+            // Check if previous activity can transfer the starting window to this activity.
+            return prev != null && prev.getActivityType() == ACTIVITY_TYPE_STANDARD
+                    && prev.mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_IDLE
+                    && (prev.mStartingData != null
+                    || (prev.mStartingWindow != null && prev.mStartingSurface != null));
         }
         return true;
     }
@@ -4873,6 +4880,12 @@
                             true /* activityChange */, true /* updateOomAdj */,
                             true /* addPendingTopUid */);
                 }
+                final ContentCaptureManagerInternal contentCaptureService =
+                        LocalServices.getService(ContentCaptureManagerInternal.class);
+                if (contentCaptureService != null) {
+                    contentCaptureService.notifyActivityEvent(mUserId, mActivityComponent,
+                            ActivityEvent.TYPE_ACTIVITY_STARTED);
+                }
                 break;
             case PAUSED:
                 mAtmService.updateBatteryStats(this, false);
@@ -6278,15 +6291,21 @@
 
         mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord);
 
-        final int resolvedTheme = evaluateStartingWindowTheme(packageName, theme,
+        final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme,
                 splashScreenTheme);
 
+        final boolean activityCreated =
+                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal();
+        // If this activity is just created and all activities below are finish, treat this
+        // scenario as warm launch.
+        final boolean newSingleActivity = !newTask && !activityCreated
+                && task.getActivity((r) -> !r.finishing && r != this) == null;
+
         final boolean shown = addStartingWindow(packageName, resolvedTheme,
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
-                prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
-                allowTaskSnapshot(),
-                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
-                mSplashScreenStyleEmpty);
+                prev != null ? prev.appToken : null,
+                newTask || newSingleActivity, taskSwitch, isProcessRunning(),
+                allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty);
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
         }
@@ -7266,41 +7285,48 @@
         }
 
         final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
-        final int parentWidth = parentBounds.width();
-        final int parentHeight = parentBounds.height();
-        float aspect = Math.max(parentWidth, parentHeight)
-                / (float) Math.min(parentWidth, parentHeight);
+        final Rect parentAppBounds = newParentConfig.windowConfiguration.getAppBounds();
+        final Rect containingBounds = new Rect();
+        final Rect containingAppBounds = new Rect();
+        // Need to shrink the containing bounds into a square because the parent orientation does
+        // not match the activity requested orientation.
+        if (forcedOrientation == ORIENTATION_LANDSCAPE) {
+            // Shrink height to match width. Position height within app bounds.
+            final int bottom = Math.min(parentAppBounds.top + parentBounds.width(),
+                    parentAppBounds.bottom);
+            containingBounds.set(parentBounds.left, parentAppBounds.top, parentBounds.right,
+                    bottom);
+            containingAppBounds.set(parentAppBounds.left, parentAppBounds.top,
+                    parentAppBounds.right, bottom);
+        } else {
+            // Shrink width to match height. Position width within app bounds.
+            final int right = Math.min(parentAppBounds.left + parentBounds.height(),
+                    parentAppBounds.right);
+            containingBounds.set(parentAppBounds.left, parentBounds.top, right,
+                    parentBounds.bottom);
+            containingAppBounds.set(parentAppBounds.left, parentAppBounds.top, right,
+                    parentAppBounds.bottom);
+        }
+
+        Rect mTmpFullBounds = new Rect(resolvedBounds);
+        resolvedBounds.set(containingBounds);
 
         // Override from config_fixedOrientationLetterboxAspectRatio or via ADB with
         // set-fixed-orientation-letterbox-aspect-ratio.
         final float letterboxAspectRatioOverride =
                 mWmService.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
-        aspect = letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
-                ? letterboxAspectRatioOverride : aspect;
+        final float desiredAspectRatio =
+                letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
+                        ? letterboxAspectRatioOverride : computeAspectRatio(parentBounds);
+        // Apply aspect ratio to resolved bounds
+        mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingAppBounds,
+                containingBounds, desiredAspectRatio, true);
 
-        // Adjust the fixed orientation letterbox bounds to fit the app request aspect ratio in
-        // order to use the extra available space.
-        final float maxAspectRatio = info.getMaxAspectRatio();
-        final float minAspectRatio = info.getMinAspectRatio();
-        if (aspect > maxAspectRatio && maxAspectRatio != 0) {
-            aspect = maxAspectRatio;
-        } else if (aspect < minAspectRatio) {
-            aspect = minAspectRatio;
-        }
-
-        // Store the current bounds to be able to revert to size compat mode values below if needed.
-        Rect mTmpFullBounds = new Rect(resolvedBounds);
+        // Vertically center if orientation is landscape. Bounds will later be horizontally centered
+        // in {@link updateResolvedBoundsHorizontalPosition()} regardless of orientation.
         if (forcedOrientation == ORIENTATION_LANDSCAPE) {
-            final int height = (int) Math.rint(parentWidth / aspect);
-            final int top = parentBounds.centerY() - height / 2;
-            resolvedBounds.set(parentBounds.left, top, parentBounds.right, top + height);
-        } else {
-            final int width = (int) Math.rint(parentHeight / aspect);
-            final Rect parentAppBounds = newParentConfig.windowConfiguration.getAppBounds();
-            final int left = width <= parentAppBounds.width()
-                    // Avoid overlapping with the horizontal decor area when possible.
-                    ? parentAppBounds.left : parentBounds.centerX() - width / 2;
-            resolvedBounds.set(left, parentBounds.top, left + width, parentBounds.bottom);
+            final int offsetY = parentBounds.centerY() - resolvedBounds.centerY();
+            resolvedBounds.offset(0, offsetY);
         }
 
         if (mCompatDisplayInsets != null) {
@@ -7342,8 +7368,6 @@
         // then they should be aligned later in #updateResolvedBoundsHorizontalPosition().
         if (!mTmpBounds.isEmpty()) {
             resolvedBounds.set(mTmpBounds);
-            // Exclude the horizontal decor area.
-            resolvedBounds.left = parentAppBounds.left;
         }
         if (!resolvedBounds.isEmpty() && !resolvedBounds.equals(parentBounds)) {
             // Compute the configuration based on the resolved bounds. If aspect ratio doesn't
@@ -7404,13 +7428,6 @@
             mIsAspectRatioApplied =
                     applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
         }
-        // If the bounds are restricted by fixed aspect ratio, the resolved bounds should be put in
-        // the container app bounds. Otherwise the entire container bounds are available.
-        final boolean fillContainer = resolvedBounds.equals(containingBounds);
-        if (!fillContainer) {
-            // The horizontal position should not cover insets.
-            resolvedBounds.left = containingAppBounds.left;
-        }
 
         // Use resolvedBounds to compute other override configurations such as appBounds. The bounds
         // are calculated in compat container space. The actual position on screen will be applied
@@ -7477,6 +7494,7 @@
         // Align to top of parent (bounds) - this is a UX choice and exclude the horizontal decor
         // if needed. Horizontal position is adjusted in updateResolvedBoundsHorizontalPosition.
         // Above coordinates are in "@" space, now place "*" and "#" to screen space.
+        final boolean fillContainer = resolvedBounds.equals(containingBounds);
         final int screenPosX = fillContainer ? containerBounds.left : containerAppBounds.left;
         final int screenPosY = containerBounds.top;
         if (screenPosX != 0 || screenPosY != 0) {
@@ -7713,6 +7731,12 @@
         return true;
     }
 
+    private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
+            Rect containingBounds) {
+        return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
+                0 /* desiredAspectRatio */, false /* fixedOrientationLetterboxed */);
+    }
+
     /**
      * Applies aspect ratio restrictions to outBounds. If no restrictions, then no change is
      * made to outBounds.
@@ -7721,17 +7745,19 @@
      */
     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
     private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
-            Rect containingBounds) {
+            Rect containingBounds, float desiredAspectRatio, boolean fixedOrientationLetterboxed) {
         final float maxAspectRatio = info.getMaxAspectRatio();
         final Task rootTask = getRootTask();
         final float minAspectRatio = info.getMinAspectRatio();
 
         if (task == null || rootTask == null
-                || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets())
-                || (maxAspectRatio == 0 && minAspectRatio == 0)
+                || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets()
+                    && !fixedOrientationLetterboxed)
+                || (maxAspectRatio < 1 && minAspectRatio < 1 && desiredAspectRatio < 1)
                 || isInVrUiMode(getConfiguration())) {
-            // We don't enforce aspect ratio if the activity task is in multiwindow unless it
-            // is in size-compat mode. We also don't set it if we are in VR mode.
+            // We don't enforce aspect ratio if the activity task is in multiwindow unless it is in
+            // size-compat mode or is letterboxed from fixed orientation. We also don't set it if we
+            // are in VR mode.
             return false;
         }
 
@@ -7739,20 +7765,30 @@
         final int containingAppHeight = containingAppBounds.height();
         final float containingRatio = computeAspectRatio(containingAppBounds);
 
+        if (desiredAspectRatio < 1) {
+            desiredAspectRatio = containingRatio;
+        }
+
+        if (maxAspectRatio >= 1 && desiredAspectRatio > maxAspectRatio) {
+            desiredAspectRatio = maxAspectRatio;
+        } else if (minAspectRatio >= 1 && desiredAspectRatio < minAspectRatio) {
+            desiredAspectRatio = minAspectRatio;
+        }
+
         int activityWidth = containingAppWidth;
         int activityHeight = containingAppHeight;
 
-        if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
+        if (containingRatio > desiredAspectRatio) {
             if (containingAppWidth < containingAppHeight) {
                 // Width is the shorter side, so we use that to figure-out what the max. height
                 // should be given the aspect ratio.
-                activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
+                activityHeight = (int) ((activityWidth * desiredAspectRatio) + 0.5f);
             } else {
                 // Height is the shorter side, so we use that to figure-out what the max. width
                 // should be given the aspect ratio.
-                activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
+                activityWidth = (int) ((activityHeight * desiredAspectRatio) + 0.5f);
             }
-        } else if (containingRatio < minAspectRatio) {
+        } else if (containingRatio < desiredAspectRatio) {
             boolean adjustWidth;
             switch (getRequestedConfigurationOrientation()) {
                 case ORIENTATION_LANDSCAPE:
@@ -7780,9 +7816,9 @@
                     break;
             }
             if (adjustWidth) {
-                activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
+                activityWidth = (int) ((activityHeight / desiredAspectRatio) + 0.5f);
             } else {
-                activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
+                activityHeight = (int) ((activityWidth / desiredAspectRatio) + 0.5f);
             }
         }
 
@@ -7806,6 +7842,13 @@
         }
         outBounds.set(containingBounds.left, containingBounds.top, right, bottom);
 
+        // If the bounds are restricted by fixed aspect ratio, then out bounds should be put in the
+        // container app bounds. Otherwise the entire container bounds are available.
+        if (!outBounds.equals(containingBounds)) {
+            // The horizontal position should not cover insets.
+            outBounds.left = containingAppBounds.left;
+        }
+
         return true;
     }
 
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 0ec0142..2ea043a 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -75,10 +75,18 @@
      * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling
      * changes.  Disabling this change will prevent the following scaling factors from working:
      * CompatModePackages#DOWNSCALE_90
+     * CompatModePackages#DOWNSCALE_85
      * CompatModePackages#DOWNSCALE_80
+     * CompatModePackages#DOWNSCALE_75
      * CompatModePackages#DOWNSCALE_70
+     * CompatModePackages#DOWNSCALE_65
      * CompatModePackages#DOWNSCALE_60
+     * CompatModePackages#DOWNSCALE_55
      * CompatModePackages#DOWNSCALE_50
+     * CompatModePackages#DOWNSCALE_45
+     * CompatModePackages#DOWNSCALE_40
+     * CompatModePackages#DOWNSCALE_35
+     * CompatModePackages#DOWNSCALE_30
      *
      * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly
      * resized to the highest enabled scaling factor e.g. 80% if both 80% and 70% were enabled.
@@ -100,6 +108,16 @@
 
     /**
      * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_85 for a package will force the app to assume it's
+     * running on a display with 85% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_85 = 189969734L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
      * CompatModePackages#DOWNSCALE_80 for a package will force the app to assume it's
      * running on a display with 80% the vertical and horizontal resolution of the real display.
      */
@@ -110,6 +128,16 @@
 
     /**
      * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's
+     * running on a display with 75% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_75 = 189969779L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
      * CompatModePackages#DOWNSCALE_70 for a package will force the app to assume it's
      * running on a display with 70% the vertical and horizontal resolution of the real display.
      */
@@ -120,6 +148,16 @@
 
     /**
      * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_65 for a package will force the app to assume it's
+     * running on a display with 65% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_65 = 189969744L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
      * CompatModePackages#DOWNSCALE_60 for a package will force the app to assume it's
      * running on a display with 60% the vertical and horizontal resolution of the real display.
      */
@@ -130,6 +168,16 @@
 
     /**
      * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_55 for a package will force the app to assume it's
+     * running on a display with 55% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_55 = 189970036L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
      * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's
      * running on a display with 50% vertical and horizontal resolution of the real display.
      */
@@ -139,6 +187,46 @@
     public static final long DOWNSCALE_50 = 176926741L;
 
     /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_45 for a package will force the app to assume it's
+     * running on a display with 45% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_45 = 189969782L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_40 for a package will force the app to assume it's
+     * running on a display with 40% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_40 = 189970038L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_35 for a package will force the app to assume it's
+     * running on a display with 35% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_35 = 189969749L;
+
+    /**
+     * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id
+     * CompatModePackages#DOWNSCALE_30 for a package will force the app to assume it's
+     * running on a display with 30% the vertical and horizontal resolution of the real display.
+     */
+    @ChangeId
+    @Disabled
+    @Overridable
+    public static final long DOWNSCALE_30 = 189970040L;
+
+    /**
      * On Android TV applications that target pre-S are not expecting to receive a Window larger
      * than 1080p, so if needed we are downscaling their Windows to 1080p.
      * However, applications that target S and greater release version are expected to be able to
@@ -291,18 +379,42 @@
             if (CompatChanges.isChangeEnabled(DOWNSCALE_90, packageName, userHandle)) {
                 return 1f / 0.9f;
             }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_85, packageName, userHandle)) {
+                return 1f / 0.85f;
+            }
             if (CompatChanges.isChangeEnabled(DOWNSCALE_80, packageName, userHandle)) {
                 return 1f / 0.8f;
             }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_75, packageName, userHandle)) {
+                return 1f / 0.75f;
+            }
             if (CompatChanges.isChangeEnabled(DOWNSCALE_70, packageName, userHandle)) {
                 return 1f / 0.7f;
             }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_65, packageName, userHandle)) {
+                return 1f / 0.65f;
+            }
             if (CompatChanges.isChangeEnabled(DOWNSCALE_60, packageName, userHandle)) {
                 return 1f / 0.6f;
             }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_55, packageName, userHandle)) {
+                return 1f / 0.55f;
+            }
             if (CompatChanges.isChangeEnabled(DOWNSCALE_50, packageName, userHandle)) {
                 return 1f / 0.5f;
             }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_45, packageName, userHandle)) {
+                return 1f / 0.45f;
+            }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_40, packageName, userHandle)) {
+                return 1f / 0.4f;
+            }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_35, packageName, userHandle)) {
+                return 1f / 0.35f;
+            }
+            if (CompatChanges.isChangeEnabled(DOWNSCALE_30, packageName, userHandle)) {
+                return 1f / 0.3f;
+            }
         }
 
         if (mService.mHasLeanbackFeature) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index c510603..bc2556a 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -221,6 +221,9 @@
     // transaction from the global transaction.
     private final SurfaceControl.Transaction mDisplayTransaction;
 
+    // The tag for the token to put root tasks on the displays to sleep.
+    private static final String DISPLAY_OFF_SLEEP_TOKEN_TAG = "Display-off";
+
     /** The token acquirer to put root tasks on the displays to sleep */
     final ActivityTaskManagerInternal.SleepTokenAcquirer mDisplayOffTokenAcquirer;
 
@@ -450,7 +453,7 @@
         mService = service.mAtmService;
         mTaskSupervisor = mService.mTaskSupervisor;
         mTaskSupervisor.mRootWindowContainer = this;
-        mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl("Display-off");
+        mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
     }
 
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
@@ -2654,12 +2657,14 @@
             Slog.d(TAG, "Remove non-exist sleep token: " + token + " from " + Debug.getCallers(6));
         }
         mSleepTokens.remove(token.mHashKey);
-
         final DisplayContent display = getDisplayContent(token.mDisplayId);
         if (display != null) {
             display.mAllSleepTokens.remove(token);
             if (display.mAllSleepTokens.isEmpty()) {
                 mService.updateSleepIfNeededLocked();
+                if (token.mTag.equals(DISPLAY_OFF_SLEEP_TOKEN_TAG)) {
+                    display.mSkipAppTransitionAnimation = true;
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2c8fceb..147260b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -34,6 +34,7 @@
 import static android.content.pm.PackageManager.FEATURE_PC;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -2545,12 +2546,13 @@
                 // We will leave the critical section before returning the leash to the client,
                 // so we need to copy the leash to prevent others release the one that we are
                 // about to return.
-                // TODO: We will have an extra copy if the client is not local.
-                //       For now, we rely on GC to release it.
-                //       Maybe we can modify InsetsSourceControl.writeToParcel so it can release
-                //       the extra leash as soon as possible.
-                outControls[i] = controls[i] != null
-                        ? new InsetsSourceControl(controls[i]) : null;
+                if (controls[i] != null) {
+                    // This source control is an extra copy if the client is not local. By setting
+                    // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of
+                    // SurfaceControl.writeToParcel.
+                    outControls[i] = new InsetsSourceControl(controls[i]);
+                    outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 9a6e444..4471f6c 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -683,8 +683,9 @@
         }
 
         // We don't apply animation for application main window here since this window type
-        // should be controlled by AppWindowToken in general.
-        if (mAttrType != TYPE_BASE_APPLICATION) {
+        // should be controlled by ActivityRecord in general. Wallpaper is also excluded because
+        // WallpaperController should handle it.
+        if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper) {
             applyAnimationLocked(transit, true);
         }
 
diff --git a/services/net/Android.bp b/services/net/Android.bp
index dd864ae..a822257 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -51,7 +51,6 @@
         // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
         // classes generated by netd_aidl_interfaces-platform-java above.
         "netd_aidl_interface-V3-java",
-        "netlink-client",
         "networkstack-client",
         "modules-utils-build_system",
     ],
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 9706d7f..e3e2708 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -37,6 +37,7 @@
 import android.provider.DeviceConfig;
 import android.util.Log;
 
+import com.android.internal.R;
 import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -302,8 +303,15 @@
             return;
         }
 
+        if (!getUploaderEnabledConfig(getContext())) {
+            return;
+        }
+
         new Thread(() -> {
             try {
+                Context context = getContext();
+                final String uploaderPkg = getUploaderPackageName(context);
+                final String uploaderAction = getUploaderActionName(context);
                 String reportUuid = mIProfcollect.report();
 
                 final int profileId = getBBProfileId();
@@ -317,13 +325,12 @@
                 }
 
                 Intent uploadIntent =
-                        new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE")
-                        .setPackage("com.google.android.apps.internal.betterbug")
+                        new Intent(uploaderAction)
+                        .setPackage(uploaderPkg)
                         .putExtra("EXTRA_DESTINATION", "PROFCOLLECT")
                         .putExtra("EXTRA_PACKAGE_NAME", getContext().getPackageName())
                         .putExtra("EXTRA_PROFILE_PATH", reportPath)
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                Context context = getContext();
 
                 List<ResolveInfo> receivers =
                         context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0);
@@ -356,4 +363,19 @@
         }
         return UserHandle.USER_SYSTEM;
     }
+
+    private boolean getUploaderEnabledConfig(Context context) {
+        return context.getResources().getBoolean(
+            R.bool.config_profcollectReportUploaderEnabled);
+    }
+
+    private String getUploaderPackageName(Context context) {
+        return context.getResources().getString(
+            R.string.config_defaultProfcollectReportUploaderApp);
+    }
+
+    private String getUploaderActionName(Context context) {
+        return context.getResources().getString(
+            R.string.config_defaultProfcollectReportUploaderAction);
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index e99113d..acf50b45 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -323,6 +323,8 @@
         when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
         doNothing().when(mWakeLock).acquire();
         doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
+        doNothing().when(mAlarmManager)
+                .setWindow(anyInt(), anyLong(), anyLong(), anyString(), any(), any());
         doReturn(mock(Sensor.class)).when(mSensorManager)
                 .getDefaultSensor(eq(Sensor.TYPE_SIGNIFICANT_MOTION), eq(true));
         doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt());
@@ -1043,24 +1045,28 @@
         mDeviceIdleController.stepLightIdleStateLocked("testing");
         verifyLightStateConditions(LIGHT_STATE_IDLE);
         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
-                longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT));
+                longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT),
+                longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
 
         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
 
         mDeviceIdleController.stepLightIdleStateLocked("testing");
         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
-                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
+                longThat(l -> l == mConstants.FLEX_TIME_SHORT));
 
         mDeviceIdleController.stepLightIdleStateLocked("testing");
         verifyLightStateConditions(LIGHT_STATE_IDLE);
         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
-                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
 
         mDeviceIdleController.stepLightIdleStateLocked("testing");
         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
-                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
+                longThat(l -> l == mConstants.FLEX_TIME_SHORT));
 
         // Test that motion doesn't reset the idle timeout.
         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
@@ -1068,7 +1074,8 @@
         mDeviceIdleController.stepLightIdleStateLocked("testing");
         verifyLightStateConditions(LIGHT_STATE_IDLE);
         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
-                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
     }
 
     ///////////////// EXIT conditions ///////////////////
@@ -1824,9 +1831,9 @@
                 .forClass(AlarmManager.OnAlarmListener.class);
         final ArgumentCaptor<AlarmManager.OnAlarmListener> motionRegistrationAlarmListener =
                 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
-        doNothing().when(mAlarmManager).set(anyInt(), anyLong(), eq("DeviceIdleController.motion"),
-                motionAlarmListener.capture(), any());
-        doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+        doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
+                eq("DeviceIdleController.motion"), motionAlarmListener.capture(), any());
+        doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
                 eq("DeviceIdleController.motion_registration"),
                 motionRegistrationAlarmListener.capture(), any());
 
@@ -1900,9 +1907,9 @@
         mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
         final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
                 .forClass(AlarmManager.OnAlarmListener.class);
-        doNothing().when(mAlarmManager)
-                .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
-        doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+        doNothing().when(mAlarmManager).setWindow(
+                anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+        doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
                 eq("DeviceIdleController.motion_registration"),
                 alarmListener.capture(), any());
         ArgumentCaptor<TriggerEventListener> listenerCaptor =
@@ -1944,9 +1951,9 @@
         mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
         final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
                 .forClass(AlarmManager.OnAlarmListener.class);
-        doNothing().when(mAlarmManager)
-                .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
-        doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+        doNothing().when(mAlarmManager).setWindow(
+                anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+        doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
                 eq("DeviceIdleController.motion_registration"),
                 alarmListener.capture(), any());
         ArgumentCaptor<SensorEventListener> listenerCaptor =
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
index da0b83e..28fcaee 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.DeviceConfig;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -63,7 +62,6 @@
     public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() {
         PlatformLogger logger = new PlatformLogger(
                 ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL),
                 mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -96,8 +94,7 @@
         int putDocumentSamplingInterval = 1;
         int batchCallSamplingInterval = 2;
         PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig);
+                ApplicationProvider.getApplicationContext(), mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
                 AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
@@ -143,7 +140,6 @@
         final String testPackageName = "packageName";
         PlatformLogger logger = new PlatformLogger(
                 ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL),
                 mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -162,7 +158,6 @@
         final String testPackageName = "packageName";
         PlatformLogger logger = new PlatformLogger(
                 ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL),
                 mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -186,7 +181,6 @@
         final String testPackageName = "packageName";
         PlatformLogger logger = new PlatformLogger(
                 ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL),
                 mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
@@ -214,7 +208,6 @@
         final String testPackageName = "packageName";
         PlatformLogger logger = new PlatformLogger(
                 ApplicationProvider.getApplicationContext(),
-                UserHandle.of(UserHandle.USER_NULL),
                 mAppSearchConfig);
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java
index b480f24..5e219a2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.Context;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -49,6 +50,7 @@
     private static final int NOTIFICATION_RESPONSIVENESS = 0;
     private static final int UNKNOWN_TIMER = 0;
 
+    private @Mock Context mContext;
     private @Mock GnssConfiguration mMockConfiguration;
     private @Mock GnssNative.GeofenceCallbacks mGeofenceCallbacks;
 
@@ -63,7 +65,7 @@
         GnssNative.setGnssHalForTest(mFakeHal);
 
         GnssNative gnssNative = Objects.requireNonNull(
-                GnssNative.create(new TestInjector(), mMockConfiguration));
+                GnssNative.create(new TestInjector(mContext), mMockConfiguration));
         gnssNative.setGeofenceCallbacks(mGeofenceCallbacks);
         mTestProvider = new GnssGeofenceProxy(gnssNative);
         gnssNative.register();
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java
index 3d03781..d728451 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java
@@ -29,9 +29,10 @@
 public class FakeAppOpsHelper extends AppOpsHelper {
 
     private static class AppOp {
-        private boolean mAllowed = true;
-        private boolean mStarted = false;
-        private int mNoteCount = 0;
+        AppOp() {}
+        boolean mAllowed = true;
+        boolean mStarted = false;
+        int mNoteCount = 0;
     }
 
     private final HashMap<String, SparseArray<AppOp>> mAppOps;
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
index f1099f0..cd70020 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java
@@ -29,8 +29,8 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
- * Version of AppOpsHelper for testing. Settings are initialized to reasonable defaults (location is
- * enabled by default).
+ * Version of SettingsHelper for testing. Settings are initialized to reasonable defaults (location
+ * is enabled by default).
  */
 public class FakeSettingsHelper extends SettingsHelper {
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
index ae70dad..bd24cfd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java
@@ -16,9 +16,14 @@
 
 package com.android.server.location.injector;
 
+import android.content.Context;
+
+import com.android.server.location.settings.FakeLocationSettings;
+
 public class TestInjector implements Injector {
 
     private final FakeUserInfoHelper mUserInfoHelper;
+    private final FakeLocationSettings mLocationSettings;
     private final FakeAlarmHelper mAlarmHelper;
     private final FakeAppOpsHelper mAppOpsHelper;
     private final FakeLocationPermissionsHelper mLocationPermissionsHelper;
@@ -32,8 +37,9 @@
     private final FakeEmergencyHelper mEmergencyHelper;
     private final LocationUsageLogger mLocationUsageLogger;
 
-    public TestInjector() {
+    public TestInjector(Context context) {
         mUserInfoHelper = new FakeUserInfoHelper();
+        mLocationSettings = new FakeLocationSettings(context);
         mAlarmHelper = new FakeAlarmHelper();
         mAppOpsHelper = new FakeAppOpsHelper();
         mLocationPermissionsHelper = new FakeLocationPermissionsHelper(mAppOpsHelper);
@@ -54,6 +60,11 @@
     }
 
     @Override
+    public FakeLocationSettings getLocationSettings() {
+        return mLocationSettings;
+    }
+
+    @Override
     public FakeAlarmHelper getAlarmHelper() {
         return mAlarmHelper;
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index 6bc3b60..f703e2e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -19,6 +19,8 @@
 import static android.app.AppOpsManager.OP_FINE_LOCATION;
 import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION;
 import static android.app.AppOpsManager.OP_MONITOR_LOCATION;
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
+import static android.location.LocationManager.GPS_PROVIDER;
 import static android.location.LocationRequest.PASSIVE_INTERVAL;
 import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
 import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
@@ -56,6 +58,8 @@
 import static org.testng.Assert.assertThrows;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.location.ILocationCallback;
 import android.location.ILocationListener;
 import android.location.LastLocationRequest;
@@ -82,6 +86,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.location.injector.FakeUserInfoHelper;
@@ -139,6 +144,10 @@
     @Mock
     private Context mContext;
     @Mock
+    private Resources mResources;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
     private PowerManager mPowerManager;
     @Mock
     private PowerManager.WakeLock mWakeLock;
@@ -161,20 +170,28 @@
         LocalServices.addService(LocationManagerInternal.class, mInternal);
 
         doReturn("android").when(mContext).getPackageName();
+        doReturn(mResources).when(mContext).getResources();
+        doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
         doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
 
-        mInjector = new TestInjector();
+        mInjector = new TestInjector(mContext);
         mInjector.getUserInfoHelper().startUser(OTHER_USER);
 
         mPassive = new PassiveLocationProviderManager(mContext, mInjector);
         mPassive.startManager(null);
         mPassive.setRealProvider(new PassiveLocationProvider(mContext));
 
+        createManager(NAME);
+    }
+
+    private void createManager(String name) {
+        mStateChangedListener = mock(LocationProviderManager.StateChangedListener.class);
+
         mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY);
         mProvider.setProviderAllowed(true);
 
-        mManager = new LocationProviderManager(mContext, mInjector, NAME, mPassive);
+        mManager = new LocationProviderManager(mContext, mInjector, name, mPassive);
         mManager.startManager(mStateChangedListener);
         mManager.setRealProvider(mProvider);
     }
@@ -1017,6 +1034,95 @@
     }
 
     @Test
+    public void testProviderRequest_AdasGnssBypass() {
+        doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+        doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
+        createManager(GPS_PROVIDER);
+
+        ILocationListener listener1 = createMockLocationListener();
+        LocationRequest request1 = new LocationRequest.Builder(5)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
+
+        assertThat(mProvider.getRequest().isActive()).isTrue();
+        assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
+        assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
+
+        ILocationListener listener2 = createMockLocationListener();
+        LocationRequest request2 = new LocationRequest.Builder(1)
+                .setAdasGnssBypass(true)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
+
+        assertThat(mProvider.getRequest().isActive()).isTrue();
+        assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
+        assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
+    }
+
+    @Test
+    public void testProviderRequest_AdasGnssBypass_ProviderDisabled() {
+        doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+        doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
+        createManager(GPS_PROVIDER);
+
+        ILocationListener listener1 = createMockLocationListener();
+        LocationRequest request1 = new LocationRequest.Builder(1)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
+
+        ILocationListener listener2 = createMockLocationListener();
+        LocationRequest request2 = new LocationRequest.Builder(5)
+                .setAdasGnssBypass(true)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
+
+        mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
+
+        assertThat(mProvider.getRequest().isActive()).isTrue();
+        assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
+        assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
+    }
+
+    @Test
+    public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() {
+        mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
+                new PackageTagsList.Builder().add(
+                        IDENTITY.getPackageName()).build());
+        doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+        doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
+        createManager(GPS_PROVIDER);
+
+        ILocationListener listener1 = createMockLocationListener();
+        LocationRequest request1 = new LocationRequest.Builder(5)
+                .setLocationSettingsIgnored(true)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
+
+        ILocationListener listener2 = createMockLocationListener();
+        LocationRequest request2 = new LocationRequest.Builder(1)
+                .setAdasGnssBypass(true)
+                .setWorkSource(WORK_SOURCE)
+                .build();
+        mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
+
+        mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(),
+                settings -> settings.withAdasGnssLocationEnabled(false));
+        mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
+
+        assertThat(mProvider.getRequest().isActive()).isTrue();
+        assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
+        assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
+    }
+
+    @Test
     public void testProviderRequest_BatterySaver_ScreenOnOff() {
         mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode(
                 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
index 04e0151..63996f0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.MockitoAnnotations.initMocks;
 
+import android.content.Context;
 import android.location.Location;
 import android.location.LocationResult;
 import android.location.provider.ProviderRequest;
@@ -58,6 +59,7 @@
     private TestInjector mInjector;
     private FakeProvider mDelegateProvider;
 
+    private @Mock Context mContext;
     private @Mock AbstractLocationProvider.Listener mListener;
     private @Mock FakeProvider.FakeProviderInterface mDelegate;
 
@@ -72,7 +74,7 @@
 
         mRandom = new Random(seed);
 
-        mInjector = new TestInjector();
+        mInjector = new TestInjector(mContext);
         mDelegateProvider = new FakeProvider(mDelegate);
 
         mProvider = new StationaryThrottlingLocationProvider("test_provider", mInjector,
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.java b/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.java
new file mode 100644
index 0000000..4d46aba
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.java
@@ -0,0 +1,54 @@
+/*
+ * 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.location.settings;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import java.io.File;
+
+public class FakeLocationSettings extends LocationSettings {
+
+    public FakeLocationSettings(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected File getUserSettingsDir(int userId) {
+        return ApplicationProvider.getApplicationContext().getCacheDir();
+    }
+
+    @Override
+    protected LocationUserSettingsStore createUserSettingsStore(int userId, File file) {
+        return new FakeLocationUserSettingsStore(userId, file);
+    }
+
+    private class FakeLocationUserSettingsStore extends LocationUserSettingsStore {
+
+        FakeLocationUserSettingsStore(int userId, File file) {
+            super(userId, file);
+        }
+
+        @Override
+        protected void onChange(LocationUserSettings oldSettings,
+                LocationUserSettings newSettings) {
+            fireListeners(mUserId, oldSettings, newSettings);
+        }
+    }
+}
+
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java b/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java
new file mode 100644
index 0000000..4b6c79b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.location.settings;
+
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.io.File;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LocationSettingsTest {
+
+    private @Mock Context mContext;
+    private @Mock Resources mResources;
+    private @Mock PackageManager mPackageManager;
+
+    private LocationSettings mLocationSettings;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+
+        doReturn(mResources).when(mContext).getResources();
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+
+        resetLocationSettings();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mLocationSettings.deleteFiles();
+    }
+
+    private void resetLocationSettings() {
+        mLocationSettings = new LocationSettings(mContext) {
+            @Override
+            protected File getUserSettingsDir(int userId) {
+                return ApplicationProvider.getApplicationContext().getCacheDir();
+            }
+        };
+    }
+
+    @Test
+    public void testLoadDefaults() {
+        doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue();
+
+        doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+        assertThat(mLocationSettings.getUserSettings(2).isAdasGnssLocationEnabled()).isFalse();
+    }
+
+    @Test
+    public void testUpdate() {
+        doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(true));
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue();
+
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(false));
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse();
+    }
+
+    @Test
+    public void testSerialization() throws Exception {
+        doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(true));
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue();
+
+        mLocationSettings.flushFiles();
+        resetLocationSettings();
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue();
+    }
+
+    @Test
+    public void testListeners() {
+        doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+        LocationSettings.LocationUserSettingsListener listener = mock(
+                LocationSettings.LocationUserSettingsListener.class);
+
+        mLocationSettings.registerLocationUserSettingsListener(listener);
+
+        ArgumentCaptor<LocationUserSettings> oldCaptor = ArgumentCaptor.forClass(
+                LocationUserSettings.class);
+        ArgumentCaptor<LocationUserSettings> newCaptor = ArgumentCaptor.forClass(
+                LocationUserSettings.class);
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(true));
+        verify(listener, timeout(500).times(1)).onLocationUserSettingsChanged(eq(1),
+                oldCaptor.capture(), newCaptor.capture());
+        assertThat(oldCaptor.getValue().isAdasGnssLocationEnabled()).isFalse();
+        assertThat(newCaptor.getValue().isAdasGnssLocationEnabled()).isTrue();
+
+        oldCaptor = ArgumentCaptor.forClass(LocationUserSettings.class);
+        newCaptor = ArgumentCaptor.forClass(LocationUserSettings.class);
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(false));
+        verify(listener, timeout(500).times(2)).onLocationUserSettingsChanged(eq(1),
+                oldCaptor.capture(), newCaptor.capture());
+        assertThat(oldCaptor.getValue().isAdasGnssLocationEnabled()).isTrue();
+        assertThat(newCaptor.getValue().isAdasGnssLocationEnabled()).isFalse();
+
+        mLocationSettings.unregisterLocationUserSettingsListener(listener);
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(true));
+        verify(listener, after(500).times(2)).onLocationUserSettingsChanged(anyInt(), any(), any());
+    }
+
+    @Test
+    public void testNonAutomotive() {
+        doReturn(false).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
+        doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
+
+        LocationSettings.LocationUserSettingsListener listener = mock(
+                LocationSettings.LocationUserSettingsListener.class);
+        mLocationSettings.registerLocationUserSettingsListener(listener);
+
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse();
+        mLocationSettings.updateUserSettings(1,
+                settings -> settings.withAdasGnssLocationEnabled(true));
+        assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse();
+        verify(listener, after(500).never()).onLocationUserSettingsChanged(anyInt(), any(), any());
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index 7d628be..68570ff 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -286,6 +286,7 @@
         ApexSessionInfo activationFailed = new ApexSessionInfo();
         activationFailed.sessionId = 1543;
         activationFailed.isActivationFailed = true;
+        activationFailed.errorMessage = "Failed for test";
 
         ApexSessionInfo staged = new ApexSessionInfo();
         staged.sessionId = 101;
@@ -309,8 +310,8 @@
 
         assertThat(apexSession1.getErrorCode())
                 .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
-        assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. Check logcat "
-                + "messages from apexd for more information.");
+        assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. "
+                + "Failed for test");
 
         assertThat(apexSession2.getErrorCode())
                 .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
index f4f9073..3c10789 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
@@ -42,7 +42,7 @@
 
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -67,7 +67,7 @@
     private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
     private Context mContext;
     private AppSearchImpl mAppSearchImpl;
-    private VisibilityStore mVisibilityStore;
+    private VisibilityStoreImpl mVisibilityStore;
     private int mGlobalQuerierUid;
 
     @Before
@@ -93,7 +93,7 @@
         // Give ourselves global query permissions
         mAppSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
-        mVisibilityStore = VisibilityStore.create(mAppSearchImpl, mContext);
+        mVisibilityStore = VisibilityStoreImpl.create(mAppSearchImpl, mContext);
         mGlobalQuerierUid =
                 mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
     }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
index 7c275e1..ec96d6a 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
@@ -65,13 +65,8 @@
         Context context = ApplicationProvider.getApplicationContext();
         mContext = new ContextWrapper(context) {
             @Override
-            public Context createContextAsUser(UserHandle user, int flags) {
-                return new ContextWrapper(super.createContextAsUser(user, flags)) {
-                    @Override
-                    public PackageManager getPackageManager() {
-                        return getMockPackageManager(user);
-                    }
-                };
+            public PackageManager getPackageManager() {
+                return getMockPackageManager(mContext.getUser());
             }
         };
     }
@@ -153,7 +148,6 @@
         final int testUid = 1234;
         PlatformLogger logger = new PlatformLogger(
                 mContext,
-                mContext.getUser(),
                 AppSearchConfig.create(DIRECT_EXECUTOR));
         PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
         when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java
similarity index 96%
rename from services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java
index 183cb86..07a728b 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java
@@ -14,10 +14,7 @@
  * limitations under the License.
  */
 
-// TODO(b/169883602): This is purposely a different package from the path so that it can access
-// AppSearchImpl methods without having to make methods public. This should be moved into a proper
-// package once AppSearchImpl-VisibilityStore's dependencies are refactored.
-package com.android.server.appsearch.external.localstorage;
+package com.android.server.appsearch.visibilitystore;
 
 import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
@@ -39,8 +36,10 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
 import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -55,7 +54,7 @@
 import java.util.Collections;
 import java.util.Map;
 
-public class VisibilityStoreTest {
+public class VisibilityStoreImplTest {
     /**
      * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
      */
@@ -64,7 +63,7 @@
     @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
     private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
     private Context mContext;
-    private VisibilityStore mVisibilityStore;
+    private VisibilityStoreImpl mVisibilityStore;
     private int mUid;
 
     @Before
@@ -90,7 +89,7 @@
         // Give ourselves global query permissions
         AppSearchImpl appSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
-        mVisibilityStore = VisibilityStore.create(appSearchImpl, mContext);
+        mVisibilityStore = VisibilityStoreImpl.create(appSearchImpl, mContext);
         mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 019254d..c572dd6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -785,7 +785,7 @@
         }
 
         @Override
-        public void getNextPage(long nextPageToken, UserHandle userHandle,
+        public void getNextPage(String packageName, long nextPageToken, UserHandle userHandle,
                 IAppSearchResultCallback callback) throws RemoteException {
             final Bundle page = new Bundle();
             page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
@@ -795,8 +795,8 @@
         }
 
         @Override
-        public void invalidateNextPageToken(long nextPageToken, UserHandle userHandle)
-                throws RemoteException {
+        public void invalidateNextPageToken(String packageName, long nextPageToken,
+                UserHandle userHandle) throws RemoteException {
         }
 
         @Override
@@ -875,13 +875,13 @@
         }
 
         @Override
-        public void persistToDisk(UserHandle userHandle, long binderCallStartTimeMillis)
-                throws RemoteException {
+        public void persistToDisk(String packageName, UserHandle userHandle,
+                long binderCallStartTimeMillis) throws RemoteException {
         }
 
         @Override
-        public void initialize(UserHandle userHandle, long binderCallStartTimeMillis,
-                IAppSearchResultCallback callback)
+        public void initialize(String packageName, UserHandle userHandle,
+                long binderCallStartTimeMillis, IAppSearchResultCallback callback)
                 throws RemoteException {
             ignore(callback);
         }
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index f880563..9044b27 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -222,61 +222,61 @@
     }
 
     /**
-     * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS}
-     * permission flag for the tag: {@code allowed-partner-apex}.
+     * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_VENDOR_APEX}
+     * permission flag for the tag: {@code allowed-vendor-apex}.
      */
     @Test
-    public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList()
+    public void readPermissions_allowVendorApex_parsesVendorApexAllowList()
             throws IOException {
         final String contents =
                 "<config>\n"
-                        + "    <allowed-partner-apex package=\"com.android.apex1\" />\n"
+                        + "    <allowed-vendor-apex package=\"com.android.apex1\" />\n"
                         + "</config>";
         final File folder = createTempSubfolder("folder");
-        createTempFile(folder, "partner-apex-allowlist.xml", contents);
+        createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
         mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
 
-        assertThat(mSysConfig.getAllowedPartnerApexes()).containsExactly("com.android.apex1");
+        assertThat(mSysConfig.getAllowedVendorApexes()).containsExactly("com.android.apex1");
     }
 
     /**
-     * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS}
-     * permission flag for the tag: {@code allowed-partner-apex}.
+     * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_VENDOR_APEX}
+     * permission flag for the tag: {@code allowed-vendor-apex}.
      */
     @Test
-    public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList_noPackage()
+    public void readPermissions_allowVendorApex_parsesVendorApexAllowList_noPackage()
             throws IOException {
         final String contents =
                 "<config>\n"
-                        + "    <allowed-partner-apex/>\n"
+                        + "    <allowed-vendor-apex/>\n"
                         + "</config>";
         final File folder = createTempSubfolder("folder");
-        createTempFile(folder, "partner-apex-allowlist.xml", contents);
+        createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
         mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
 
-        assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty();
+        assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty();
     }
 
 
     /**
-     * Tests that readPermissions works correctly without {@link SystemConfig#ALLOW_APP_CONFIGS}
-     * permission flag for the tag: {@code allowed-partner-apex}.
+     * Tests that readPermissions works correctly without {@link SystemConfig#ALLOW_VENDOR_APEX}
+     * permission flag for the tag: {@code allowed-oem-apex}.
      */
     @Test
-    public void readPermissions_notAllowAppConfigs_doesNotParsePartnerApexAllowList()
+    public void readPermissions_notAllowVendorApex_doesNotParseVendorApexAllowList()
             throws IOException {
         final String contents =
                 "<config>\n"
-                        + "    <allowed-partner-apex package=\"com.android.apex1\" />\n"
+                        + "    <allowed-vendor-apex package=\"com.android.apex1\" />\n"
                         + "</config>";
         final File folder = createTempSubfolder("folder");
-        createTempFile(folder, "partner-apex-allowlist.xml", contents);
+        createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all but ALLOW_APP_CONFIGS flag */ ~0x08);
+        mSysConfig.readPermissions(folder, /* Grant all but ALLOW_VENDOR_APEX flag */ ~0x400);
 
-        assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty();
+        assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty();
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
index f4eb2de..32988ef 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
@@ -68,6 +68,38 @@
     }
 
     @Test
+    public void testRampSegments_withPwleDurationLimit_splitsLongRamps() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 0, /* endFrequency= */ -1, /* duration= */ 25),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude*/ 1,
+                        /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 5)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0.32f,
+                        /* startFrequency= */ 0, /* endFrequency= */ -0.32f, /* duration= */ 8),
+                new RampSegment(/* startAmplitude= */ 0.32f, /* endAmplitude= */ 0.64f,
+                        /* startFrequency= */ -0.32f, /* endFrequency= */ -0.64f,
+                        /* duration= */ 8),
+                new RampSegment(/* startAmplitude= */ 0.64f, /* endAmplitude= */ 1,
+                        /* startFrequency= */ -0.64f, /* endFrequency= */ -1, /* duration= */ 9),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude*/ 1,
+                        /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 5));
+
+        VibratorInfo vibratorInfo = new VibratorInfo.Builder(0)
+                .setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)
+                .setPwlePrimitiveDurationMax(10)
+                .build();
+
+        // Update repeat index to skip the ramp splits.
+        assertEquals(4, mAdapter.apply(segments, 2, vibratorInfo));
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
     public void testStepAndRampSegments_withoutPwleCapability_keepsListUnchanged() {
         mAdapter = new StepToRampAdapter(50);
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 3862d75..71c05b5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -48,6 +48,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.NotificationChannel;
@@ -111,6 +112,8 @@
     NotificationUsageStats mUsageStats;
     @Mock
     IAccessibilityManager mAccessibilityService;
+    @Mock
+    KeyguardManager mKeyguardManager;
     NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
     private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
             1 << 30);
@@ -153,6 +156,7 @@
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
         when(mVibrator.hasFrequencyControl()).thenReturn(false);
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
 
         long serviceReturnValue = IntPair.of(
                 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -174,6 +178,7 @@
         mService.setScreenOn(false);
         mService.setUsageStats(mUsageStats);
         mService.setAccessibilityManager(accessibilityManager);
+        mService.setKeyguardManager(mKeyguardManager);
         mService.mScreenOn = false;
         mService.mInCallStateOffHook = false;
         mService.mNotificationPulseEnabled = true;
@@ -496,6 +501,94 @@
     }
 
     @Test
+    public void testLockedPrivateA11yRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mService.setAccessibilityManager(accessibilityManager);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+                ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+                .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+    }
+
+    @Test
+    public void testLockedOverridePrivateA11yRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
+        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mService.setAccessibilityManager(accessibilityManager);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+                ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+                .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+    }
+
+    @Test
+    public void testLockedPublicA11yNoRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mService.setAccessibilityManager(accessibilityManager);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+                ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+                .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification(), event.getParcelableData());
+    }
+
+    @Test
+    public void testUnlockedPrivateA11yNoRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mService.setAccessibilityManager(accessibilityManager);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+                ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+                .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification(), event.getParcelableData());
+    }
+
+    @Test
     public void testBeepInsistently() throws Exception {
         NotificationRecord r = getInsistentBeepyNotification();
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index a522b5c..1f543a1 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -94,6 +94,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
@@ -2425,6 +2426,8 @@
         when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
+        when(mPreferencesHelper.deleteNotificationChannel(eq(PKG), anyInt(),
+                eq(mTestNotificationChannel.getId()))).thenReturn(true);
         reset(mListeners);
         mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
@@ -2433,6 +2436,22 @@
     }
 
     @Test
+    public void testDeleteChannelOnlyDoExtraWorkIfExisted() throws Exception {
+        List<String> associations = new ArrayList<>();
+        associations.add("a");
+        when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid)))
+                .thenReturn(associations);
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+                eq(mTestNotificationChannel.getId()), anyBoolean()))
+                .thenReturn(null);
+        reset(mListeners);
+        mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
+        verifyNoMoreInteractions(mListeners);
+        verifyNoMoreInteractions(mHistoryManager);
+    }
+
+    @Test
     public void testDeleteChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 3a51ff2..23da02c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -3333,6 +3333,17 @@
     }
 
     @Test
+    public void testDeleted_twice() throws Exception {
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+                mAppOpsManager, mStatsEventBuilderFactory);
+
+        mHelper.createNotificationChannel(
+                PKG_P, UID_P, createNotificationChannel("id", "id", 2), true, false);
+        assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
+        assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
+    }
+
+    @Test
     public void testDeleted_recentTime() throws Exception {
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                 mAppOpsManager, mStatsEventBuilderFactory);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 4e261de..4872ec5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -401,6 +401,7 @@
         assertFitted();
 
         final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
+        final Rect currentAppBounds = mActivity.getWindowConfiguration().getAppBounds();
         final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
 
         final int notchHeight = 100;
@@ -428,8 +429,8 @@
         // Because the display cannot rotate, the portrait activity will fit the short side of
         // display with keeping portrait bounds [200, 0 - 700, 1000] in center.
         assertEquals(newDisplayBounds.height(), currentBounds.height());
-        assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
-                currentBounds.width());
+        assertEquals(currentAppBounds.height() * newDisplayBounds.height()
+                / newDisplayBounds.width(), currentAppBounds.width());
         assertFitted();
         // The appBounds should be [200, 100 - 700, 1000].
         final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 128602d..1b84927 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2226,7 +2226,14 @@
         }
 
         @Override
-        public long getLastTimeAnyComponentUsed(String packageName) {
+        public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) {
+            if (!hasPermissions(
+                    callingPackage, android.Manifest.permission.INTERACT_ACROSS_USERS)) {
+                throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission");
+            }
+            if (!hasPermission(callingPackage)) {
+                throw new SecurityException("Don't have permission to query usage stats");
+            }
             synchronized (mLock) {
                 // Truncate the returned milliseconds to the boundary of the last day before exact
                 // time for privacy reasons.
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index eac21b4..5183e5b 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -863,7 +863,12 @@
         }
 
         private void enforceCallingPermission(String permission) {
-            PermissionUtil.checkPermissionForPreflight(mContext, mOriginatorIdentity, permission);
+            if (PermissionUtil.checkPermissionForPreflight(mContext, mOriginatorIdentity,
+                    permission) != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException(
+                        "Identity " + mOriginatorIdentity + " does not have permission "
+                                + permission);
+            }
         }
 
         private void enforceDetectionPermissions(ComponentName detectionService) {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1953af4..e000265 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1018,6 +1018,16 @@
     // this magic number is a bug ID
     public static final long ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION = 157233955L;
 
+    /**
+     * Enable READ_PHONE_NUMBERS or READ_PRIVILEGED_PHONE_STATE protections on
+     * {@link TelecomManager#getPhoneAccount(PhoneAccountHandle)}.
+     * @hide
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+    // bug ID
+    public static final long ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION = 183407956L;
+
     private static final String TAG = "TelecomManager";
 
 
@@ -1351,6 +1361,9 @@
      * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
      * resources which can be used in a user interface.
      *
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_NUMBERS} for applications targeting API
+     * level 31+.
      * @param account The {@link PhoneAccountHandle}.
      * @return The {@link PhoneAccount} object.
      */
@@ -1358,7 +1371,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getPhoneAccount(account);
+                return service.getPhoneAccount(account, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getPhoneAccount", e);
             }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 18afde7..6f286d9 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -79,7 +79,7 @@
     /**
      * @see TelecomManager#getPhoneAccount
      */
-    PhoneAccount getPhoneAccount(in PhoneAccountHandle account);
+    PhoneAccount getPhoneAccount(in PhoneAccountHandle account, String callingPackage);
 
     /**
      * @see TelecomManager#getAllPhoneAccountsCount
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index c679d04..c563e06 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -52,6 +52,7 @@
     data: [
         ":com.android.apex.apkrollback.test_v1",
         ":com.android.apex.cts.shim.v2_prebuilt",
+        ":StagedInstallTestApexV2_WrongSha",
         ":TestAppAv1",
     ],
     test_suites: ["general-tests"],
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index e633c87..6a62304 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -179,6 +179,26 @@
         assertThat(info.isStagedSessionFailed()).isTrue();
     }
 
+    @Test
+    public void testApexActivationFailureIsCapturedInSession_Commit() throws Exception {
+        int sessionId = Install.single(TestApp.Apex1).setStaged().commit();
+        assertSessionReady(sessionId);
+        storeSessionId(sessionId);
+    }
+
+    @Test
+    public void testApexActivationFailureIsCapturedInSession_Verify() throws Exception {
+        int sessionId = retrieveLastSessionId();
+        assertSessionFailedWithMessage(sessionId, "has unexpected SHA512 hash");
+    }
+
+    private static void assertSessionFailedWithMessage(int sessionId, String msg) {
+        assertSessionState(sessionId, (session) -> {
+            assertThat(session.isStagedSessionFailed()).isTrue();
+            assertThat(session.getStagedSessionErrorMessage()).contains(msg);
+        });
+    }
+
     private static void assertSessionReady(int sessionId) {
         assertSessionState(sessionId,
                 (session) -> assertThat(session.isStagedSessionReady()).isTrue());
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index ccd63f9..5d7fdd1 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -56,6 +56,7 @@
     @Rule
     public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
     private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex";
+    private static final String APEX_WRONG_SHA = "com.android.apex.cts.shim.v2_wrong_sha.apex";
     private static final String APK_A = "TestAppAv1.apk";
     private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
 
@@ -322,6 +323,27 @@
         runPhase("testFailStagedSessionIfStagingDirectoryDeleted_Verify");
     }
 
+    @Test
+    public void testApexActivationFailureIsCapturedInSession() throws Exception {
+        // We initiate staging a normal apex update which passes pre-reboot verification.
+        // Then we replace the valid apex waiting in /data/app-staging with something
+        // that cannot be activated and reboot. The apex should fail to activate, which
+        // is what we want for this test.
+        runPhase("testApexActivationFailureIsCapturedInSession_Commit");
+        final String sessionId = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+        assertThat(sessionId).isNotEmpty();
+        // Now replace the valid staged apex with something invalid
+        getDevice().enableAdbRoot();
+        getDevice().executeShellCommand("rm /data/app-staging/session_" + sessionId + "/*");
+        final File invalidApexFile = mHostUtils.getTestFile(APEX_WRONG_SHA);
+        getDevice().pushFile(invalidApexFile,
+                "/data/app-staging/session_" + sessionId + "/base.apex");
+        getDevice().reboot();
+
+        runPhase("testApexActivationFailureIsCapturedInSession_Verify");
+    }
+
     private List<String> getStagingDirectories() throws DeviceNotAvailableException {
         String baseDir = "/data/app-staging";
         try {
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 4ce78aa..dc338ae 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -70,6 +72,14 @@
     public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-";
     private static int sGatewayConnectionConfigCount = 0;
 
+    private static VcnGatewayConnectionConfig buildTestConfig(
+            String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams) {
+        return buildTestConfigWithExposedCaps(
+                new VcnGatewayConnectionConfig.Builder(
+                        gatewayConnectionName, tunnelConnectionParams),
+                EXPOSED_CAPS);
+    }
+
     // Public for use in VcnGatewayConnectionTest
     public static VcnGatewayConnectionConfig buildTestConfig() {
         return buildTestConfigWithExposedCaps(EXPOSED_CAPS);
@@ -83,10 +93,9 @@
                 TUNNEL_CONNECTION_PARAMS);
     }
 
-    // Public for use in VcnGatewayConnectionTest
-    public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) {
-        final VcnGatewayConnectionConfig.Builder builder =
-                newBuilder().setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU);
+    private static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(
+            VcnGatewayConnectionConfig.Builder builder, int... exposedCaps) {
+        builder.setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU);
 
         for (int caps : exposedCaps) {
             builder.addExposedCapability(caps);
@@ -95,6 +104,11 @@
         return builder.build();
     }
 
+    // Public for use in VcnGatewayConnectionTest
+    public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) {
+        return buildTestConfigWithExposedCaps(newBuilder(), exposedCaps);
+    }
+
     @Test
     public void testBuilderRequiresNonNullGatewayConnectionName() {
         try {
@@ -193,4 +207,46 @@
 
         assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle()));
     }
+
+    private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) {
+        final IkeSessionParams ikeParams =
+                IkeSessionParamsUtilsTest.createBuilderMinimum()
+                        .setAuthPsk(ikePsk.getBytes())
+                        .build();
+        return TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams);
+    }
+
+    @Test
+    public void testTunnelConnectionParamsEquals() throws Exception {
+        final String connectionName = "testTunnelConnectionParamsEquals.connectionName";
+        final String psk = "testTunnelConnectionParamsEquals.psk";
+
+        final IkeTunnelConnectionParams tunnelParams = buildTunnelConnectionParams(psk);
+        final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams);
+
+        final IkeTunnelConnectionParams anotherTunnelParams = buildTunnelConnectionParams(psk);
+        final VcnGatewayConnectionConfig anotherConfig =
+                buildTestConfig(connectionName, anotherTunnelParams);
+
+        assertNotSame(tunnelParams, anotherTunnelParams);
+        assertEquals(tunnelParams, anotherTunnelParams);
+        assertEquals(config, anotherConfig);
+    }
+
+    @Test
+    public void testTunnelConnectionParamsNotEquals() throws Exception {
+        final String connectionName = "testTunnelConnectionParamsNotEquals.connectionName";
+
+        final IkeTunnelConnectionParams tunnelParams =
+                buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskA");
+        final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams);
+
+        final IkeTunnelConnectionParams anotherTunnelParams =
+                buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskB");
+        final VcnGatewayConnectionConfig anotherConfig =
+                buildTestConfig(connectionName, anotherTunnelParams);
+
+        assertNotEquals(tunnelParams, anotherTunnelParams);
+        assertNotEquals(config, anotherConfig);
+    }
 }